Jinny Song
Jinny Song

Reputation: 125

Why the 'fetch function' automatically call the 'parse function' on backbone.js collection?

I am trying to parse my json file into Backbone collection and model as like below.

This is .json file

[
{
    "type": "rect",
    "x": 10,
    "y": 10,
    "w": 100,
    "h": 100,
    "color": "red"
},
{
    "type": "arc",
    "x": 210,
    "y": 20,
    "w": 200,
    "h": 150,
    "color": "blue"
}
]

And I also have .html file as like below.

    <script>
    $(function() {
        var JSONModel = Backbone.Model.extend({});

        var MyCollection = Backbone.Collection.extend({
            model : JSONModel,
            url : 'profiles.json',
            initialize : function() {
                alert("init");
            },
            parse : function(response) {

                for (var i = 0; i < response.length; i++) {
                    var tmpModel = new JSONModel();
                    tmpModel.set({
                        type : response[i].type,
                        x : response[i].x,
                        y : response[i].y,
                        w : response[i].w,
                        h : response[i].h,
                        color : response[i].color
                    });
                    this.add(tmpModel);
                    alert("inserting" + i);
                }

                return response;
            }

        });

        var collection = new MyCollection();
        collection.fetch();
        alert(collection.length);


    });
</script>


Q.

1.In this code, why fetch function call parse function?

2.Is there any other function which is called from fetch function?

3.Do you think how can I fix this code to get the json object? I cannot get the 'collection.length' in this code.

Please help.

Upvotes: 2

Views: 1295

Answers (2)

T J
T J

Reputation: 43156

The reason you're not getting the expected length is that fetch() is asynchronous. You need to check for the length once the promise is resolved (fetch is done).

All you need to do is this:

var MyCollection = Backbone.Collection.extend({
  model: JSONModel,
  url: 'profiles.json',
  initialize: function() {
    console.log("init");
  }
});

var collection = new MyCollection();
collection.fetch({
  success: function(collection, response) {
    console.log(collection.length);
  }
});

If you define a parse method, backbone will execute it before updating the model and executing other callbacks (passed in the options), this is required only if you want to modify the fetched data before processing it further (updating the model/collection, passing to callbacks etc).

For example, assume your .json contains the following:

{
 "someKey": "some Info",
 "data": [{
  "type": "rect",
  "x": 10,
  "y": 10,
  "w": 100,
  "h": 100,
  "color": "red"
 },
 {
  "type": "arc",
  "x": 210,
  "y": 20,
  "w": 200,
  "h": 150,
  "color": "blue"
 }]
}

Then you'd want to parse this and return the actual array like:

parse: function(response){
  console.log(response.someKey); // do somethig with this if required
  return response.data;
}

In your case, the .json contains an array of objects, backbone will parse each object in the array into a model of the specified type and add it in your collection. There is no need to specify a parse method.

And yes, there are other methods that gets called internally, for example sync, toJSON etc. each of them has their own duty (and can be overridden) which is given in the documentation.

Upvotes: 1

vijayP
vijayP

Reputation: 11502

Please have a look at my comments below for your question:

1. In this code, why fetch function call parse function?

Ans: While extending Backbone.Collection you have overridden the parse callback function and Backbone internally calls the parse function whenever we try to fetch the collection. This is the standard call. I don't think you have to Or can change this behavior.

2. Is there any other function which is called from fetch function?

Ans: As far as I know I don't think any other callback function is getting called while calling fetch. Why you are looking for it? What is your requirement for this point? Any specific reason?

3. Do you think how can I fix this code to get the json object? I cannot get the 'collection.length' in this code.

Ans: You will have to wait till the time we receive the data and hence we need to add success handler in following way:

collection.fetch({
  success: function(collection){
    // Callback triggered only after receiving the data.
    console.log(collection.length); 
  }
});

Upvotes: 2

Related Questions