Can someone tell me how to re fetch a Backbone collection after calling collection's create
function when I create a new model?
When I call fetch
on my collection after creating new model, sometimes I'm getting that model and sometimes not.
My problem is when I create a new model in my collection, I'm not getting the id back of my model and then I can't update it immediately, I need to refresh the page and then I got the id of the created model.
I tried with listenTo
but I can't use it because I need to send more collections to one function.
And that my view for my bootstrap modal, on save I'm creating my model it persists to database and I'm getting all attributes in my console when I create it except models id.
Backbone view:
app.types.EditView = Backbone.View.extend({
tagName: "div",
$container: $('#containerEdit'),
template: _.template($('#itemEdit-template').html()),
events:
{
"click .save": "save",
},
initialize: function(options)
{
this.options = options;
this.$container.html(this.render());
this.start();
this.end();
},
render: function()
{
this.$el.html(this.template());
return this.$el;
},
save: function()
{
console.log("save");
$('#openModal').modal('hide');
var dan = this.model.dan_u_tjednu_usera.datum;
var mjesec = this.model.dan_u_tjednu_usera.mjesecBrojevi;
var godina = this.model.dan_u_tjednu_usera.godina;
var start = $("#start").val();
var end = $("#end").val();
var user_id = this.model.user.id;
this.model.shifts.create({day: dan, month: mjesec, year: godina, time_from: start, time_to: end, user_id: user_id});
this.options.model.el.html($("<td href='#openModal' width='25%' align='center' class='list-group test' scope='row'>" + start + " - " + end + " " + "Admin" + "</td>"));
this.model.shifts.fetch({sync: true});
console.log("test", this.model.shifts);
}
Here you can see that in my response im not getting the id attribute, on create.
And here you can see when i click on my cell i log my collection and i have not the id attribute of the created model here. And im not getting the id attribute it too when i log this.model
This is because the request sent to the server when you call
Collection.create
is asynchronous, the Javascript code will continue to execute before the server receives and responds to the request.If you want to have the Model updated with the ID coming back from the server, you can specify
{wait: true}
in theCollection.create
call. This will mean that the Collection will not have the Model added straight away, but instead only when the server responds (successfully).In this case you should not run the
fetch
immediately afterwards, as it will also need to wait for the create operation to complete. You should setup any following actions to trigger when the create operation has completed. Here is an example:Backbone's create
There's no need to fetch a collection after a create, the model
id
and any other field are automatically merged within itsattributes
hash.Fetch after model creation
While mikeapr4 is not wrong, his example could be improved.
The
{ wait: true }
is unnecessary if the only problem comes from the fetch, not from the model already being inside the collection.Also,
once
should be avoided as it's the "old" way, and insteadlistenToOnce
should be used. See Difference between ListenTo and on.If you really want to fetch once a model is created, using events is overkill here, and instead, using the success callback is best:
Other notes on your code
There are no
sync
option in Backbone. Only a"sync"
event and async
function.Avoid using the global jQuery selector (like
$('.class-name')
) and instead, whenever the element is within the view's element, usethis.$('.class-name')
.Also, cache the jQuery element to avoid the costly search of the
find
method.Like
$("#start")
could be cache and reused. Only reset the cached elements when re-rendering.The Backbone
.render
function should returnthis
by convention.Then, your rendering call should look like: