Backbone - not parse each model in collection after fetch

10,109

When creating models for insertion in a collection, Backbone passes the future collection as an option to the model constructor which in turns forwards this option to parse. You could check this property and abort the parsing as needed:

var Task  = Backbone.Model.extend({
    parse : function(response, options){
        if (options.collection) return response;
        return response.tasks[0];
    }
});
var TaskList = Backbone.Collection.extend({
    model: Task,
    parse : function(response){
        return response.tasks;
    }
});

And a demo http://jsfiddle.net/nikoshr/dfMgR/

Share:
10,109
Gabriel
Author by

Gabriel

Updated on July 23, 2022

Comments

  • Gabriel
    Gabriel almost 2 years

    How to prevent parse function for model in collection fetching?

        $(function() {
        var Task = Backbone.Model.extend({
            url : function() {
                    return this.urlRoot + this.id;
            },
            urlRoot: 'index.php?c=light&a=list_tasks_bb&ajax=true&task=',
            parse: function (response, options) {
                console.log(options);
                console.log(response);
                return response;
            }
        });
    
        var TaskList = Backbone.Collection.extend({
            model: Task,
            url: 'index.php?c=light&a=list_tasks_bb&ajax=true',
    
            initialize: function () {
    
            },
            parse: function (response, options) {
                return response.tasks;
            }
        });
    
        var Light = Backbone.Router.extend({
            el: $('#light'),
            routes: {
                "tasks/:id": "taskAction",
                "*page": "defaultAction",
            },
    
            initialize: function () {
                _this = this;
                this.tasks = new TaskList();
                this.users = new UserList();
            },
    
            taskAction: function(id) {
                this.task = new Task({id: id});
                $.when (
                    this.task.fetch()
                ).then(function(zzz) {
                    new TaskView({model: _this.task}).render();
                });
            },
            defaultAction: function(page) {
                $.when (
                    this.tasks.fetch(),
                    this.users.fetch()
                ).then (function() {
                    new TaskListView({collection: _this.tasks}).render();
                });
            }
        });
    });
    

    I have one model and one collection which I get through ajax fetch. I have no opportunity to change backend, so the json structure of tasks list is:

    "contents": {},
    "current": false,
    "errorCode": 0,
    "errorMessage": "",
    "u": 4,
    "tasks": [{
        "id": "12250",
        "t": "ZZZ",
        "cid": "24",
        "c": "2013-08-22 11:36:32",
        "dd": "02.09.2013",
        "sd": "02.09.2013",
        "pr": "300",
        "pid": "0",
        "atid": "1:4",
        "s": 0,
        "dl": ""
    }, {
        "id": "12307",
        "t": "ZZZ",
        "cid": "42",
        "c": "2013-08-28 11:14:44",
        "dd": "05.09.2013",
        "sd": "28.08.2013",
        "pr": "200",
        "pid": "0",
        "atid": "1:4",
        "s": 0,
        "dl": ""
    }, {
        "id": "12326",
        "t": "ZZZ",
        "cid": "2",
        "c": "2013-08-29 09:55:34",
        "dd": "31.08.2013",
        "sd": "29.08.2013",
        "pr": "200",
        "pid": "0",
        "atid": "1:4",
        "s": 0,
        "dl": ""
    }],
    "events": []
    

    This is the reason why I'm using parse for collection. In this step everything is fine. JSON structure for single task is:

    "contents": {},
    "current": false,
    "errorCode": 0,
    "errorMessage": "",
    "u": 4,
    "tasks": [{
        "id": "12250",
        "t": "ZZZZ",
        "cid": "24",
        "c": "2013-08-22 11:36:32",
        "dd": "02.09.2013",
        "sd": "02.09.2013",
        "pr": "300",
        "pid": "0",
        "atid": "1:4",
        "text": "XXXXX",
        "s": 0,
        "dl": ""
    }],
    "comments": [{
        "id": "48178",
        "text": "CCCC",
        "cid": "4",
        "con": "23.08.2013"
    }],
    "events": []
    

    So i need parse again for fetch single task after "task.fetch()". After I added parse function in model it working fine until I started fetch collection, because after collection parse I already have correct model data, but model parse callback for each model again.

    Do I have correct way to fix this or better will be try to change backend?

    PS Sure, I can do something like this:

      if(response.tasks) {
        return response.tasks[0];
      } else {
        return response;
      }
    

    But I think it's not correct solution.

  • Gaston Sanchez
    Gaston Sanchez about 10 years
    THANK YOU! you saved me A LOT of time.
  • topless
    topless about 10 years
    It took me a day to spot the re-parse issue, savior for real.