1

I am creating a model-like Class that, when initialized, fires off an AJAX request. I want to store the response of that request as a property of the new object, so that I can use the data it returns. Problem is, the value of 'this' within the promise (.done) is the XHR object, not the object.

How am I thinking about this wrong?

function TweetData() {

        this.tweetList = [];

        var data = $.getJSON('data/tweets.json'); 

        data.done(function(data){

            for (var i = 0; i < data.length; i++) {
                var obj = data[i];
                this.tweetList.push(obj.text);

            }

        });

    } //end constructor
Bryce Johnson
  • 6,689
  • 6
  • 40
  • 51
  • 1
    possible duplicate of [How to access the correct \`this\` / context inside a callback?](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) – Felix Kling Apr 16 '14 at 02:43
  • FWIW, I would restructure the code to get a better control flow. Right now, `new TweetData` returns an instance even though the data hasn't completely loaded yet. You don't know when the instance is fully usable. A better approach would be to use a static factory method, which loads the data, constructs the instance and returns it via a promise/callback. – Felix Kling Apr 16 '14 at 02:46
  • @FelixKling Interesting. If I understand you, you're basically saying this is a way to make sure the whole model is built before something else starts using it. I'm at the very beginning of this project, but that addresses a concern I am starting to feel right off the bat. Any favorite resources on properly using static factory methods? If not, I'll Google it. Thanks! – Bryce Johnson Apr 16 '14 at 02:50
  • Exactly. And no, I have no reference in particular. You could just add a method to `TweetData` itself, e.g. `TweetData.get = function(){...}`, and than get an instance with something like `TweetData.get().done(...)`. `TweetData` can still be your constructor function, but instead of loading the data inside of it, you pass it *to* when you construct an instance inside `get`. Could also be used as a singleton then if desired. – Felix Kling Apr 16 '14 at 02:54

1 Answers1

2
function TweetData() {

    this.tweetList = [];
    var tweet=this;

    var data = $.getJSON('data/tweets.json'); 

    data.done(function(data){

        for (var i = 0; i < data.length; i++) {
            var obj = data[i];
            // 'tweet' is created outside of the callback
            // and is then passed into the data.done promise
            tweet.tweetList.push(obj.text);
        }

    });

} //end constructor
Mr. Meeseeks
  • 1,841
  • 2
  • 21
  • 37
juvian
  • 15,875
  • 2
  • 37
  • 38
  • you're right... I thought I tried that earlier using 'self', not 'tweet', and it didn't work. Not sure what I changed between now and then, but thanks for reminding me of this! – Bryce Johnson Apr 16 '14 at 02:42
  • @BryceJohnson the thing is about the `this` reference you used, inside the inner function is no more in scope so you need an outside var reference in order to recall it. – Roko C. Buljan Apr 16 '14 at 02:44