Backbone.js Error - Missed TypeError: Object [object Object] does not have a 'set' method

My code is:

I am new to Backbone.js and trying to create an application with Backbone.js and PHP. When I try to call add on the router, I get the error message:

Uncaught TypeError: Object [object Object] does not have a 'set' method.

Please help me find my mistake.

Thanks.

  // Models window.Users = Backbone.Model.extend({ urlRoot:"./bb-api/users", defaults:{ "id":null, "name":"", "email":"", "designation":"" } }); window.UsersCollection = Backbone.Collection.extend({ model:Users, url:"./bb-api/users" }); // Views window.AddUserView = Backbone.View.extend({ template:_.template($('#new-user-tpl').html()), initialize:function(){ this.model.bind("click", this.render, this); }, render:function(){ $(this.el).html(this.template(this.model.toJSON())); return this; }, events:{ "click .add":"saveUser" }, saveUser:function(){ alert('saveUser'); this.model.set({ name:$("#name").val(), email:$("#email").val(), designation:$("#designation").val() }); if(this.model.isNew()){ this.model.create(this.model); } return false; } }); // Router var AppRouter = Backbone.Router.extend({ routes:{ "":"welcome", "users":"list", "users/:id":"userDetails", "add":"addUser" }, addUser:function(){ this.addUserModel = new UsersCollection(); this.addUserView = new AddUserView({model:this.addUserModel}); $('#content').html(this.addUserView.render().el); } }); var app = new AppRouter(); Backbone.history.start(); 
+7
source share
2 answers

As stated in the comments, the problem here begins here:

 this.addUserModel = new UsersCollection(); this.addUserView = new AddUserView({model:this.addUserModel}); 

and ends here:

 saveUser:function(){ alert('saveUser'); this.model.set({ 

By going through the collection instead of the model, you create confusion, and as a result, in the saveUser function saveUser you try to call the Backbone.Model ( set ) method on the Backbone.Model instance.


Note. Starting with version 1.0.0, Backbone.Collection now has a set method. In previous versions, such as the one used by the question author, this method was instead called update .


There are several steps you can take to clarify this code. First, I would rename your models and collection classes so that it is clear that the model is the only form, and the collection is the plural form:

window.Users => window.User

window.UsersCollection => window.Users

Then I will create a new User model instead of the Users collection and pass it to your view:

 this.addUserModel = new User(); this.addUserView = new AddUserView({model:this.addUserModel}); 

Finally, I will remove the following lines:

 if(this.model.isNew()){ this.model.create(this.model); } 

Firstly, the model will always be new (since you just created it before transferring it), but more importantly, you do not need to call the Collection create method, because this method creates a new model when you already have one. Perhaps you should add the following instead:

 this.model.save(); 

if you intend to save the model on your server.

Since you already specified urlRoot for the model, this should be all you need to create a new model, pass it to your view, add your attributes based on DOM elements to your view, and finally save your server attributes to this model.

+1
source

I think you are facing a problem with the scope of objects. When an event is fired, it sends an event object to this function. Just try, it might work Declare a global variable with the current view inside the initialization

 initialize : function(){ self = this; } 

then change this to self,

  saveUser:function(){ alert('saveUser'); self.model.set({ name:$("#name").val(), email:$("#email").val(), designation:$("#designation").val() }); if(self.model.isNew()){ self.model.create(this.model); } return false; } 
0
source

All Articles