Question

I want to relate to backbone models to each other. I've a student model and collection and a project model and collection. One student model holds a nested collection of projects. Like you see below. This works fine!!

window.Student = Backbone.Model.extend({
    urlRoot : "/api/student",
    initialize : function() {

    },

    idAttribute : 'bid',

    defaults : {
        "bid" : null,
        "vorname" : "",
        "nachname" : "",
        "email" : "",
        "projekte" : new ProjektCollection()
    },
    parse : function(response) {
        console.log(response);
        response.projekte = new ProjektCollection(response.projekte);
        return response;
    },
});

window.StudentCollection = Backbone.Collection.extend({
    model : Student,
    url : "/api/student",

    parse : function(response) {
        this.subalbums.reset(response.subalbum);
        delete response.subalbum;
        return response;
    }
});

See the JSON I receive from the server.

{
"name":"Jon",
"beschreibung":"echt so",
"videourl":"invalidURL",
"studenten": [{"bid":1,"vorname":"M","nachname":"mf","email":"m.d@d.de"}],
"modulnummer":"5110",
"bid":101,
"images":["1.jpg","2.jpg","3.jpg"],
"bilddir":"38b3eff8baf56627478ec76a704e9b52"
}

My problem starts as soon as I add a StudentCollection to the Projekt model. The the StudentCollection and the ProjektCollection are not defined. Here is my Projekt model/collection code

window.Projekt = Backbone.Model.extend({

    idAttribute : 'bid',

    initialize : function(options) {

    },

    defaults : {
        "name" : "",
        "beschreibung" : "",
        "videourl" : "",
        "modulnummer" : "",
        "bid" : null,
        "pictures" : '',
        "kommentare" : "",

            // this line breaks it together with the parse function
        "studenten" : new StudentCollection(),

            // this line works
        // "studenten" : '',

        "inPortfolio" : 'false',
        "bilddir" : "",
        "titelbild" : "../img/placeholder.png"

    },

    // breaks it as well
    parse : function(response) {
        console.log(response);
        response.studenten = new StudentCollection(response.studenten);
        return response;
    }
});

window.ProjektCollection = Backbone.Collection.extend({
    initialize : function(options) {
        if (options) {
            this.modulnummer = options.modulnummer;
            this.portfolio = options.portfolio;
        };
    },

    model : Projekt,

});

this is order the I load the scripts in my index.html and below that you see the error message in displayed in the console. I also put the code in a JSFiddle

    <script src="js/models/projektModel.js"></script>
    <script src="js/models/studentModel.js"></script>

Uncaught ReferenceError: StudentCollection is not defined projektModel.js:23
Uncaught ReferenceError: ProjektCollection is not defined studentModel.js:14
Uncaught ReferenceError: ProjektCollection is not defined modulmodel.js:22

thanks

Was it helpful?

Solution

They rely on each other to be defined, but they load sequently, meaning that one gets loaded while the other does not:

window.Projekt = Backbone.Model.extend({
...
 defaults : {
    ...
    "studenten" : new StudentCollection(),
 }
}

At this point in time, StudentCollection is not defined.

Solution 1 - Use Backbone Relational

What you are trying to do is create a dependency between the models. The way I see it is:

Project Has Many Student.
Student Has Many Projects.

So you're trying to create a many-to-many relationships.

I suggest you try the following library: http://backbonerelational.org/

It'll help you do exactly what you wish.

Solution 2 - Make defaults Async

You can return a function instead of an object in defaults, this means that it gets evaluated when declaring the object, instead of when it is instantiated.

You can simple solve this by returning a function in defaults instead of an object like so:

    defaults : function() {

    var ProjectCollection = new window.ProjektCollection();

    return {
        "bid" : null,
        "vorname" : "",
        "nachname" : "",
        "email" : "",
        "projekte" : ProjectCollection
    }
},

See a working fiddle here: http://jsfiddle.net/yVSEv/1/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top