2
var RippleId = Backbone.Model.extend({
    initialize: function(toresolve) {
        this.url= config.rippleaccount.id.urlModel+toresolve;
        this.set('id', toresolve)
    }
});

var RippleIds = Backbone.Collection.extend({
    model: RippleId,

    createIdList: function(toresolves) {
        var self = this;
        _.each(toresolves, function(toresolve) {

            var model = new RippleId(toresolve);
            model.fetch({
                success: function(model,response) {
                    self.add(model);
                }
            });

        });
    }
});

var toresolvelist = new rippleids();    
toresolvelist.createIdList(toresolves);

toresolvelist.toJSON() doesn't return anything (instead of the collection's objects).

I guess it's a problem of waiting that the collection has been correctly populated but I thought it was ok because I wait for model fetching success before adding it.

When I console.log(toresolvelist) it shows me that the result is here. But I can't access it through .get or toJSON so I guess console.log is cheating me.

I'm having a hard time identifying what the problem is and I can't solve it.

Thanks a lot in advance!

nikoshr
  • 32,926
  • 33
  • 91
  • 105
François Richard
  • 6,817
  • 10
  • 43
  • 78
  • http://stackoverflow.com/questions/11459244/backbone-js-empty-array-attribute/11463190#11463190 and http://stackoverflow.com/questions/8413500/backbone-js-populating-a-collection/8415515#8415515 or http://stackoverflow.com/questions/26781970/returning-a-backbone-collection-and-iterating-through-not-with-a-view/26782761#26782761 – nikoshr Dec 05 '14 at 14:44
  • thanks diging into this – François Richard Dec 05 '14 at 14:50
  • Actually I understand the problem but still can't solve it properly ;. =/ – François Richard Dec 05 '14 at 15:45

1 Answers1

1

To get a complete list of your models, you need to wait for each of the XHR calls to resolve. This can be done with jquery.when on the values returned by model.fetch :

var RippleIds = Backbone.Collection.extend({
    model: RippleId,

    createIdList: function(toresolves) {
        var self = this, xhrs = [];

        xhrs = _.map(toresolves, function(toresolve) {
            var model = new RippleId(toresolve);
            var xhr = model.fetch().then(function() {
                self.add(model);
            });
            return xhr;
        });

        // promise that will resolve when all fetches have completed
        var combined = $.when.apply(null, xhrs);

        // event triggered when all models have been instantiated
        combined.then(function() {
            self.trigger('allin');
        });

        return combined;
    }
});

var toresolvelist = new rippleids();    
var promise = toresolvelist.createIdList(toresolves);

// with an event
toresolvelist.on('allin', function() {
    console.log('get model with an event', toresolvelist.get(1));
});

// with a promise
promise.then(function() {
    console.log(toresolvelist.toJSON());
});

And a demo http://jsfiddle.net/nikoshr/13mz3r3y/4/

nikoshr
  • 32,926
  • 33
  • 91
  • 105
  • var toresolvelist = new rippleids(); toresolvelist.createIdList(toresolves); – François Richard Dec 05 '14 at 16:26
  • The problem is that I would like access my collections from the outside var toresolvelist = new rippleids(); toresolvelist.createIdList(toresolves); toresolvelist.get("someid") or toresolvelist.toJSON is not working From the outside how can I be sure my collections is ready ? thanks again! – François Richard Dec 05 '14 at 16:32
  • Outside the callbacks? You can't, the asynchronous nature of the operations means you have to wait, somehow, that the fetches have completed either with promises or events. – nikoshr Dec 05 '14 at 16:35
  • Ok but how and when can I can access models once my collection has been instanciated ? mycollection.get("model"); doesn't work. – François Richard Dec 05 '14 at 16:41
  • do I have to override the collection getter ? – François Richard Dec 05 '14 at 16:44
  • `mycollection.get` does work, once the model has been added http://jsfiddle.net/nikoshr/13mz3r3y/4/ – nikoshr Dec 05 '14 at 16:49
  • ok now this is obvious I just had to chain the returned promise. You rocks I learned a lot thank you very much! – François Richard Dec 05 '14 at 16:55
  • What's kinda surprising is that this solution could be included in the backbone library ... I mean this problem is really common – François Richard Dec 05 '14 at 17:06