Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js error - Uncaught TypeError: Object [object Object] has no method 'set'

Tags:

backbone.js

My Code:

I am new to Backbone.js and trying to build an app with Backbone.js and PHP. When I am trying to call add in the router, I am getting error:

Uncaught TypeError: Object [object Object] has no method 'set'.

Please help me to 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();
like image 793
Nag Avatar asked Jun 26 '12 12:06

Nag


1 Answers

As suggested in the comments, the problem starts here here:

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

and finishes here:

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

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


Note: As of version 1.0.0 Backbone.Collection now has a set method. In previous versions, such as the one used by the question's author, that method was instead called update.


There are several steps you can take to clarify this code. For starters, I would rename your model and collection classes so that it's clear that the model is the singular form and the collection is the plural form:

window.Users => window.User

window.UsersCollection => window.Users

Next, I would create a new User model, instead of a Users collection, and pass that to your view:

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

Finally, I'd remove these lines:

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

For one thing, the model will always be new (as you just created it before passing it in), but more importantly you don't need to call the Collection's create method because that method creates a new model, when you already have one created. Perhaps what you should add instead is :

this.model.save();

if your intent is to save the model to your server.

Since you already specified a urlRoot for the model, that should be all you need to create a new model, pass it to your view, have your view fill in its attributes based on DOM elements, and finally save that model's attributes to your server.

like image 109
machineghost Avatar answered Oct 10 '22 20:10

machineghost