2

Thanks to @asgoth, I am able to use AngularJS $http service to retrieve stock prices from Yahoo as described here: Cannot read response from AngularJS $resource JSONP get from Yahoo Finance

In the "getHistoricalPrice" function, it puts the price inside an array, which is inside an object. From inside that function, I am able to access the price and write it to console.

The function returns the object to where it is called from. From there, I can successfully write the entire object out to console. However, I cannot access the elements of this object. I tried many different ways, but still cannot access the data in the object. You can see the code at http://jsfiddle.net/curt00/LTazR/2/ or below:

angular.module('app', ['ngResource']);

function AppCtrl($scope, $http, $resource) {

var historical_price = getHistoricalPrice("AAPL", 'start date is hard coded', 'end date is hard coded');
console.log("after calling historical price: ", historical_price);  // historical_price is an object and all of the correct data is outputted to console here, but I cannot access its elements directly from Javascript.

for(var key in historical_price) {
    console.log("key =",key);  // this outputs "key = list"
}

console.log("after calling getHistoricalPrice: ", historical_price.list[0][1]);  // Cannot access this as browser console gives error: TypeError: Cannot read property '1' of undefined
console.log("after calling getHistoricalPrice: ", historical_price['list'][0][1]);  // Cannot access this as browser console gives error: TypeError: Cannot read property '1' of undefined
console.log("after calling getHistoricalPrice: ", historical_price[0][1]);  // Cannot access this as browser console gives error: TypeError: Cannot read property '1' of undefined


function getHistoricalPrice(symbol, start, end) {

    var query = 'select * from csv where url=\'http://ichart.yahoo.com/table.csv?s=' + symbol + '&a=' + '11' + '&b=' + '19' + '&c=' + '2012' + '&d=' + '11' + '&e=' + '19' + '&f=' + '2012' + '&g=d&ignore=.csv\'';


    var url = 'http://query.yahooapis.com/v1/public/yql?q=' + fixedEncodeURIComponent(query) + '&format=json&callback=JSON_CALLBACK';

    var histData = {};

    $http.jsonp(url, {timeout: 30000}).success(function(json) {
        var list = [];


        var result = json.query.results.row;

        result.shift(); // remove the header (columns) row
        angular.forEach(result, function(row) {
            list.push([(new Date(row.col0)).getTime()/1000, parseFloat(row.col4)]);

        });
        list.sort(function(val1, val2) {
            return val1[0] - val2[0];
        });
        histData.list = list;
        console.log('Loaded historical data',histData.list[0][1],', for ' + symbol);  // This works and gives the price
    });

    return histData;
}

var fixedEncodeURIComponent = function(str) {
    return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
};



}


Any help or suggestions to solve this problem is greatly appreciate!

2
  • You use getHistoricalPrice() before its definition. Commented Dec 20, 2012 at 19:52
  • @DarinKolev Thanks for your suggestion. From where I call the function, I can successfully write the entire object out to console and I can see all of the correct data in the object's arrays and data in the console. However, I cannot access the elements directly via Javascript. Commented Dec 20, 2012 at 23:06

4 Answers 4

1

It's a matter of timing.

In lines 12-14 you are trying to access histData.list before it has been populated. This is because this code is run before the success callback to the $http.jsonp function is executed.

Any code that depends on that callback being completed must be in the callback or in a function called in the callback.

3
  • Thanks BobS for your suggestion. From where I call the function, I can successfully write the entire object out to console and I can see all of the object's arrays and data in the console. Doesn't this mean that it was populated? However, I cannot access the elements of this object. Nevertheless, I will try your suggestion. Commented Dec 20, 2012 at 22:12
  • I tried putting in a callback function into my local files. The callback did not get executed. You can get an idea of what I did at my updated jsFiddle: jsfiddle.net/curt00/LTazR/7 I welcome any other suggestions. Commented Dec 21, 2012 at 0:32
  • I got the callback to work, but I have the exact same situation as before. When I write the object to console, all of the contents (array) are correct, but I cannot access the array with Javascript from where the function is called. Commented Dec 21, 2012 at 1:15
1

See my answer on https://stackoverflow.com/a/13967709/1916258

A great way to debug the Yahoo api is using the YQL Console: http://developer.yahoo.com/yql/console/

Info about the different posibilities (which stock info) can be found on http://www.gummy-stuff.org/Yahoo-data.htm

Edit: there was still a problem with function fixedEncodeURIComponent. It should encode quotes (") too:

var fixedEncodeURIComponent = function(str) {
    return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A").replace(/\"/g, "%22");
};
1

BobS is right, you aren't timing things correctly. Also you declared fixedEncodeURIComponent after you had called it. This was resulting in an immediate error when I loaded up the jsfiddle.

While you were passing the callback through to your function correctly, you weren't actually calling it. I stripped out all the post processing of the json as you have some other errors involving the query and just implemented the callback so you can see it working.

After the request is finished and you're still in the success function you need to add

if(typeof(callback) === "function"){
    callback();
}

This calls that function you passed in and runs it. Here is a working jsFiddle of it: http://jsfiddle.net/LTazR/22/

I also updated a new variable i created call output so you can see it changing.

0

Thanks to everybody for providing suggestions.

I solved the problem by using AngularJS' $scope variable, such as $scope.symbol[user].price. I created this variable before calling the getHistoricalPrice function and then in that function, after the result is returned from $http.jsonp, I put the value into the $scope variable, as such:

$scope.symbol[user].price = row.col4;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.