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.
OR
OR
OR
Default 'url' property of a Backbone.Model object is as below. Backbone.js doc says:
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.
After have understood the @tkone 's explanation...
If you still want to have a dynamic
Model.url
you always can delay its construction to run time, try this:You can set url as option in fetch function, like this:
Well the answer here is that you want to do:
The URL isn't part of the instance of the model itself, but rather an attribute of the
MyModel
object that you're creating your model instance from. Therefore, you'd just set it like it was an normal JavaScript object property.set
is used only when the data you're setting (or conversely getting withget
) is actually an attribute of the data you want to send/receive from the server.But why you're changing the URL is the question we should be asking. The idea behind Backbone's model/collection system is that you speak to a REST endpoint and each model has a corresponding endpoint.
Like you've got a blog and that blog has an "entry" object which is available at:
And you've got a Backbone model for Entry:
Now when you
save
orfetch
Backbone knows how this works.So like you're making a new model:
This would then make Backbone do an HTTP POST request to
/rest/entry
with the body:(When you do your
mod.set({url: '/some/other/url'});
you're actually adding a field calledurl
to the dataset, so the server would send"url": "/some/other/url"
as part of that JSON POST body above:The server would then respond with an HTTP 200 (or 201) response with the same model, only with, like, say, and ID attached:
And that's not what you're looking for, right?)
Now you've got this model and it's got an ID. This means if you change it:
Backbone now makes an HTTP PUT request on
/rest/entry/1
to update the resource on the server.The server sees that you're talking about ID 1 on the
/rest/entry/
endpoint, so knows to update an existing record (and send back an HTTP 200).TL;DR
Don't change the URL, Backbone will. Make a new model for a new piece of data.