karyboy
karyboy

Reputation: 317

javascript this refers to same object after ajax callback

I am trying to work with an oauth library for javascript to fetch tweets . I have created an object that takes in the url for the twitter timeline to fetch and puts it in a column. The code is

   lister=function(opts) {
    this.setresource =lister.setresource;
    this.config = lister.config;
    this.config.resource = opts;
    this.putTweet = lister.putTweet;
    this.listerstrap = lister.listerstrap;
    this.addStrip = lister.addStrip;
    this.setTweets = lister.setTweets;
    this.addTweets = lister.addTweets;

}    

Now, if I create two new objects of lister ,

    var l1 = new lister('user1'); //user1 and user2 refer to url of the timelines 
    l1.listerstrap();
    var l2 = new lister('user2');
    l2.listerstrap();

The listerstrap function is :

     lister.listerstrap = function () {
   this.addStrip().setresource().addTweets();

   }

The problem happens in addTweets()

     lister.addTweets = function () {

   var _ = this;
   oauth.get(twiapi + _.config.resource, function (res) {
       _.setTweets(JSON.parse(res.text));
       console.log(_.config.resource);  // * 
   });

At * , the this (_) refers to the same (l2 instance) and hence the tweets from both resources are set into the same column when setTweets is called

Is this a closure problem ?

Edit: I am trying to set tweets into different columns based on the timeline or lists(as is done in say Tweetdeck , where there is a different column for each list). Though I get the tweets from both urls but they are set into the same column. _ contains the reference to the div element for each column I created in addStrip(). But somehow _ refers to the same instance in the callback . I want it to set the tweets into their respective columns

Upvotes: 0

Views: 177

Answers (2)

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76423

The problem isn't the addTweets method, if you read my previous answer: forget about it.

The problem is this:

this.config = lister.config;
this.config.resource = opts;

your constructor assigns a reference to an object, the object itself is not copied. So by assigning a reference to an instance, and then changing the referenced object, you're changing the object that is referenced by all instances.

The quick fix would be to change this.config = lister.config; to something like:

this.config = {foo: 'bar', something: 'else', resource: opts};//each time the constructor is called, create a new object literal

But please, do look into working with prototypes, because assigning references to properties of the function object, that also doubles as a constructor is not the best approach.

Update:

In response to the OP's comment: What you're seeing makes perfect sense. You're creating a new instance, setting the single config.resource object (there is only one) to User1, and the addTweets function is invoked. This function performs an asynchronous request. Asynchronous is something that is all too often overlooked, but very important in this case: before the callback function (that uses the config.resource value) is invoked, you create a new instance, and then the config.resource property is changed. The callback function isn't invoked 'till after the second instance is constructed. That's why the config.resource value is changed in that split second between calling addTweets and the async callback being invoked, because that's when the second instance is created. It's as simple as that, really.

Upvotes: 1

user123444555621
user123444555621

Reputation: 153184

I'm pretty sure that the _ refers to different instances. The problem is that you're overwriting properties of the shared config object when you do this:

this.config = lister.config;
this.config.resource = opts;

So, your l1 and l2 always have the very same config object. As soon as you instantiate l2, it overwrites the resource property.

You probably want to create a clone:

this.config = clone(lister.config);

where clone may be some implementation of your choice.

Upvotes: 1

Related Questions