ismnoiet
ismnoiet

Reputation: 4169

Why can't get Backbone collection models when using a defined function?

Let's say we have an instance of a given collection (url is specified inside the collection definition), for example :

var collection = new SomeCollection(),
    async = collection.fetch();

When i use an anonymous callback inside done method it is working just fine, like the following example :

async.done(function(){
    console.log('models are : ',collection.models)    
});

But when i define a global function and try to use it instead of the previous done callback, to organize the code little bit, i get an empty models array :

function done(collection){
   console.log('models are : ',collection.models) 
} 


async.done(done(collection));

What is exactly the problem here ? Why is it taking the collection state before the fetch call ?

Note : I've tried also to use .bind,.call,.apply but it is not working !.

Thank you in advance.

Upvotes: 0

Views: 74

Answers (3)

T J
T J

Reputation: 43166

The issue with the sample code you've provided is that you're not passing done method to then(), but it's return value as Volodymyr Synytskyi explained in his answer.


The jQuery xhr object isn't aware of the existence of backbone.js (for example a parse method defined in collection/model based on which backbone updates collection/model)

When the request succeeds, it's success callbacks will be fired. There is no guarantee that when these fire, backbone would've finished creating all the models based on the response.

This is why backbone provides a success callback, which will be fired after backbone is done with its activities.

You can pass your global handler as the success callback which will be called with collection/model, response, options as the arguments in that order.

function done(collection,response,options){
  console.log('models are : ',collection.models)
}

var collection = new SomeCollection(),
collection.fetch({
 success: done
});

Upvotes: 1

Vytalyi
Vytalyi

Reputation: 1695

How about this?

var collection = new SomeCollection(),
    async = collection.fetch({
        success: done
    });


function done(collection, response, options) {
   console.log('models are : ', collection.models) 
} 

Upvotes: 1

Volodymyr Synytskyi
Volodymyr Synytskyi

Reputation: 4055

async.done takes function as an argument. The problem is you actually pass the result of function as an argument to async.done. You need to pass function as an argument without applying it.

Try the following code:

function done(collection){
  console.log('models are : ',collection.models) 
} 

function success(collection){
  console.log('response: ',collection) 
}     

var collection = new SomeCollection(),
async = collection.fetch();

// you can use success or done method
// you can bind collection argument by yourself
async.success(success);
async.done(done.bind(this, collection));

Upvotes: 2

Related Questions