Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8882711
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T20:38:48+00:00 2026-06-14T20:38:48+00:00

I was building a small app for adding and deleting li from ul using

  • 0

I was building a small app for adding and deleting li from ul using Backbonejs.One of the SO members cymen helped me code it, using that i tailored the code a little.currently if i add one element and delete , it works , but the second time i add an element (to ul) and go to delete it , i get

Uncaught TypeError: Cannot call method ‘remove’ of undefined

Pasting my code here ,

HTML :

<input type="text" id="name">
<button id="add">Add</button>
<ul id="mylist"></ul>

JS:

$(function(){

        var myCollection = Backbone.Collection.extend();

        var myView = Backbone.View.extend({

            el:$('body'),

            tagName:'li',

            initialize : function(e){
                this.collection.bind("add",this.render,this);
                this.collection.bind("remove",this.render,this);
            },

            events:{
                'click #add' : 'addfoo'                
            },

            addfoo : function(){
               var myname= $('#name').val();
               $('#name').val('');               
               this.collection.add({name:myname});
            },

            render : function(){

                $('#mylist').empty();
                this.collection.each(function(model){
                    console.log("myView");
                    var remove = new myRemoveView({model:model});
                    remove.render();
                });
            }
        });

        var myRemoveView = Backbone.View.extend({

        el:$('body'),

        events:{
            'click .button':'removeFoo'
        },

        removeFoo : function(){
            console.log("here");

            this.model.collection.remove(this.model);
        },

        render : function(){
            console.log("second view");
            $('#mylist').append('<li>'+this.model.get('name') + "<button class='button'>"+"delete"+"</button></li>");
            return;
        }


        });
        var view = new myView({collection: new myCollection()});
            });

Two things i did not understand :

i) in the removeFoo function , we write

this.model.collection.remove(this.model)

shouldnt this have been this.collection.model.remove , something of that sort ?

ii) i add a li to ul , then i delete it , when i add another li (appending to ul works perfect) but this time when i go to delete it throws me the above error : Uncaught TypeError :cannot call method ‘remove’ of undefined

can you please help me figure out these 2 doubts in my code , btw SO member cymen’s code works like a charm only my tailored code (above) is giving me errors.

SO member cymen’s code : JS Fiddle for his code

Thank you

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T20:38:50+00:00Added an answer on June 14, 2026 at 8:38 pm

    First of all, your myRemoveView is using <body> as its el:

    var myRemoveView = Backbone.View.extend({
        el:$('body'),
    

    That means that every time you hit the delete button, you’re going to trigger removeView on every single myRemoveView you’ve made. That’s certainly not what you want to happen and part of the reason that cymen is using tagName: 'li'. There are two general rules for views and their els:

    1. One view per el and one el per view. You don’t want views sharing the same el because of the event handling problem; doubly so you don’t want several instances of the same view sharing an el.
    2. The view’s el should be the part of the DOM that the view cares about, no more and no less. This makes cleaning up quite easy, just delete the DOM element associated with your view and most things go away with it (DOM events in particular); for non-DOM events, we have a remove method on views.

    Another thing, your view shouldn’t (generally) be messing with the DOM outside it’s own el. This looks very odd:

    render : function(){
        $('#mylist').append(...);
        return;
    }
    

    The caller should be responsible for figuring out where your el goes, your view should only concern itself with things happen inside it, some other view should be responsible for #mylist. Also, render methods conventionally return this so that you can do this:

    $(x).append(some_view.render().el);
    

    to put them into the DOM.

    Specifying both tagName and el in a view:

    var myView = Backbone.View.extend({
        el: $('body'),
        tagName: 'li',
    

    is pointless, the tagName will be ignored and el will be used.

    You’re also using Backbone 0.5.3 in your fiddle. You should be using the latest versions whenever possible.

    If we correct the above, then everything starts working (again):

    var myView = Backbone.View.extend({
        //...
        render: function() {
            $('#mylist').empty();
            this.collection.each(function(model) {
                var remove = new myRemoveView({
                    model: model
                });
                $('#mylist').append(remove.render().el);
            });
        }
        //...
    });
    

    and:

    var myRemoveView = Backbone.View.extend({
        tagName: 'li',
        //...
        render: function() {
            this.$el.text(this.model.get('name'));
            this.$el.append("<button class='button'>delete</button>");
            return this;
        }
    });
    

    Demo: http://jsfiddle.net/ambiguous/2z4SA/1/


    So what sort of craziness was going on with your original version? The key is el: $('body') in your myRemoveView. First we’ll add a little logging method to myRemoveView to make it easier to watch what happens:

    _log: function(method) {
        console.log(
            method,
            ': model =', this.model.cid,
            ' got-collection =', this.model.collection ? 'yes' : 'no',
            ' view =', this.cid
        );
    }
    

    Note that cid is an internal unique ID that Backbone creates, it is just a convenient way to keep track of things. Then we’ll call this._log in removeFoo and render:

    removeFoo: function() {
        this._log('removeFoo');
        if(this.model.collection)
            this.model.collection.remove(this.model);
    },
    render: function() {
        this._log('render');
        $('#mylist').append('<li>' + this.model.get('name') + "<button class='button'>" + "delete" + "</button></li>");
        return;
    }
    

    Here’s a simple process that should show you were everything goes wrong:

    1. Add a to the list.
    2. Add b to the list.
    3. Hit a‘s delete button.

    You can follow along here: http://jsfiddle.net/ambiguous/yLYNL/

    First we’ll add a and this pops up in the console:

    render : model = c1  got-collection = yes  view = view2
    

    Then we add b and see this:

    render : model = c1  got-collection = yes  view = view4
    render : model = c3  got-collection = yes  view = view5
    

    Your myView render redraws the whole collection so we see c1 for a and c3 for the new b. So far so good, everything makes sense.

    Now, when we’ll try to delete a; first we see that we removeFoo on a:

    removeFoo : model = c1  got-collection = yes  view = view2
    

    That will trigger a myView#render which redraws the whole collection. The whole collection is just b at this point so we see c3 rendered again and everything still makes sense:

    render : model = c3  got-collection = yes  view = view6
    

    But now we see everything go sideways:

    removeFoo : model = c1  got-collection = no   view = view4
    removeFoo : model = c3  got-collection = yes  view = view5 
    

    You’ll see c3 show up because you have two myRemoveView instances (one for a and one for b) bound to the same el so both of them will see the click .delete event, it just so happens that c1 sees it first.

    But what is that c1 doing there? That’s the one that doesn’t have a collection, that’s the the one that is triggering your original error. You never detach your myRemoveViews from events on <body> so you have a zombie: even though the <li> is gone, the view is still bound to <body> through the view’s delegate call. So you have a zombie view that references a zombie model, zombies zombies everywhere and you left your zombie fighting kit in the car. But why doesn’t c1 have a collection? Well, you did :

    this.model.collection.remove(this.model)
    

    on c1 to remove it from the collection; removing a model from a collection removes the model’s collection because, well, the model is no longer in a collection.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a relatively small app that Im building using vb.net 2.0, and nant.
I'm building a small app that calculate hash from any given file to multiple
Right now I'm building a small app that imports data from a spreadsheet and
I am building a small app using PhoneGap HTML/CSS. Now my problem is that
I am building a small app that uses backbone.js on the client side, node.js/socket.io
I am building small app that will only display products in various categories. And
I'm building a small web app that allows users to list their goals. I
I'm building a small app that takes things entered into an input field and
I'm building a web app that has a grid of many small scrollable divs
I am building a small app that I can use to do Interval Training,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.