pedalpete
pedalpete

Reputation: 21536

populating nested collection with nested json

Solution in my route

Myapp.Routes = Backbone.Router.extend({
   init: function(){
        user = new User();
        user.fetch({user,
                     success: function(response){
                             user.classlist = new classes(response.attributes.classes);
           });

   }

});

I've got a serialized json array being returned from my server, and I am trying to put the nested objects into my nested collections.

This answer, I thought was going to get me there, but I'm missing something. How to build a Collection/Model from nested JSON with Backbone.js

The json which I am trying to populate my nested model with is

{first_name: "Pete",age: 27, classes: [{class_name: "math", class_code: 42},{class_name: "french", class_code: 18}]}

I create my user model

MyApp.Models.Users = = Backbone.Model.extend({

    initialize: function(){
        this.classlist = new MyApp.Collections.ClassList();

        this.classlist.parent = this;

    }

});

I had tried to follow the example on the other page, and use

      this.classlist = new MyApp.Collections.ClassList(this.get('classes'));

        this.classlist.parent = this;

but this.get('classes') returns undefined.

I've also tried getting the classes array through this.attributes.classes, but that is also undefined.

------------updated to include re-initialize -------------------- The function where I am initializing the user and classes is in the User routes and is called re-initialize. I use this function to fetch the user and their classes and store the object.

re_initialize: function(id){
            user = new MyApp.Models.User();
            MyApp.editingClasses.url = 'classes/'+id;
            MyApp.editingClasses.fetch({
                        success: function(response){
                        MyApp.editingClasses.parse(response);
                        }
            });

        new MyApp.Views.ClassesInput();
    },

As you can see, I'm calling the parse explicitly in the success function, but it isn't adding the classes to the collection.

I can't include the 'collection' because for some reason I can't access it in backbone. the user model, after getting returned to backbone includes the classes array, which I am trying to put into the ClassList collection.

The user model object copied from the javascript terminal looks like this.

attributes: Object
created_at: "2012-01-05T16:05:19Z"
id: 63
classes: Array[3]
   0: Object
   created_at: "2012-01-18T20:53:34Z"
   id: 295
   teacher_id: 63
   class_code: 42
   updated_at: "2012-01-18T20:53:34Z"
   class_name: math
   __proto__: Object
  1: Object
  2: Object
  length: 3
  __proto__: Array[0]

Upvotes: 3

Views: 5681

Answers (2)

3logy
3logy

Reputation: 2712

Okay! you can maybe fetch the classes this way :

Model :

window.person = Backbone.Model.extend({
 defaults: { }
});

Collection :

window.ClassesCollection = Backbone.Collection.extend({
 model: person,  
 url: "http://your/url/data.json",
 parse: function(response){
   return response.classes;
 }
});

Router :

window.AppRouter = Backbone.Router.extend({
 routes: {
  ""  : "init"
 },

 init: function(){      
   this.classesColl = new ClassesCollection();
   this.classesColl.fetch();
   this.classesView = new ClassesView({collection: this.classesColl});     
 }
 });

View : (for rendering every classes)

window.ClassesView = Backbone.View.extend({
  el: $('...'),
  template: _.template($("...").html()),

  initialize: function() {
    this.collection.bind("reset", this.render, this);
  },
  render: function(collection) {

    _.each( collection.models, function(obj){ 
      ...
      //obj.get('class_name') or obj.get('class_code')
      ... 
    }, this );
       ...
    return this;
  }
});

Upvotes: 4

satchmorun
satchmorun

Reputation: 12477

You can use the parse function to pre-process the server response:

MyApp.Models.Users = Backbone.Model.extend({
  parse: function(response) {
    var classesJSON = response.classes;
    var classesCollection = MyApp.Collections.ClassList(classesJSON);
    response.classes = classesCollection;
    return response;
  }
});

var user = new MyApp.Models.Users();
user.fetch();

// You should now be able to get the classlist with:
user.get('classes');

That said, the approach suggested in the other question should also work. It could be that when your initialize function is called, the model hasn't yet been populated with the data?

For example, if you're doing:

var user = new MyApp.Models.Users();

It won't have any attributes yet to give to the classlist collection. Could that be your problem?

Upvotes: 9

Related Questions