Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone.js change url parameter of a Model and fetch does not update data fetched

I have the following Model:

window.MyModel = Backbone.Model.extend({
     initialize: function(props){
          this.url = props.url;
     } 

     parse: function(){

          // @override- parsing data fetched from URL
     }


});

 // instantiate
  var mod = new MyModel({url: 'some/url/here'});

I use this global variable 'mod' to fetch some data into this model from backend.

 // fetch

 mod.fetch({
       success: function(){ ...},
       error: ...

 });

All above works well.... My Issue: I want to reuse this model by changing resetting the url and call fetch but it does not update the url somehow. I have tried the following:

  mod.fetch({ 
       data: {url:'/some/other/url'},
       postData: true,
       success: function(){ //process data},
       error: ...
  });


 mod.set({url: '/some/other/url'});
 // called fetch() without data: and postData: attributes as mentioned in previous

How do I set the url for my model so that I could call fetch() and it fetches data from updated url? Am I missing something. Thanks for any pointers..

UPDATE 1: Basically, I am unable to get updated values if I did

    model.set({url: 'new value'}); 

followed by

    model.fetch();

'model' is a global variable. Creating a fresh instance of 'model' works:

    model = new Model({url:'/some/other/url'}); 
    model.fetch();

however, works as required. Does this mean that a model instance is permanently attached to a url and it cannot be reset?

ANSWER TO MY QUESTION in UPDATE 1 Model instance is not permanently attached to a url. It can be reset dynamically. Please read through @tkone's thorough explanation and then @fguillens' solution for a better understanding.

like image 330
Vikram Avatar asked Jul 27 '12 19:07

Vikram


2 Answers

You can set url as option in fetch function, like this:

var mod = new MyModel();
mod.fetch({
   url: '/some/other/url',
   data: {}
});
like image 175
Yuriy Korman Avatar answered Oct 21 '22 10:10

Yuriy Korman


model.urlRoot = "/your/url"

OR

model.urlRoot = function(){ return "/your/url"; }

OR

model.url = "/your/url"

OR

model.url = function(){ return "/your/url"; }

Default 'url' property of a Backbone.Model object is as below. Backbone.js doc says:

Default URL for the model's representation on the server -- if you're using Backbone's restful methods, override this to change the endpoint that will be called.

url: function() {
  var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError();
  if (this.isNew()) return base;
  return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
},

Clearly, It first gets the value of urlRoot, if not available, it will look at the url of the collection to which model belongs. By defining urlRoot instead of url has an advantage of falling back to collection url in case urlRoot is null.

like image 26
Venkat Kotra Avatar answered Oct 21 '22 10:10

Venkat Kotra