Uncaught TypeError: Cannot call method 'replace' of undefined underscore.js

17,431

I'd guess that your problem is where you're storing #cart_template in the DOM:

<div id="cartlist">
    <script type="text/template" id="cart_template">
    </script>
</div>

You create your CartList like this:

var cart_view = new CartList({ el: $("#cartlist").html(myCart.showCart()) });

When you say this:

$("#cartlist").html(myCart.showCart())

everything that was inside #cartlist is gone, in particular, #cart_template is gone. Then inside CartList, you try to do this:

_.template( $("#cart_template").html(), {} );

But there is no more #cart_template at that point so $('#cart_template').html() is undefined and that's where your error comes from: _.template will call replace internally but you're giving it undefined as the template instead of a string.

The solution is to move your #cart_template outside #cartlist.

I'd also recommend that you not pass the el to the view's constructor, your view should create its own el and the caller should put that el where it wants it in the DOM. That way the view is wholly responsible for its element and you'll have fewer zombie and event problems.

Share:
17,431
titi
Author by

titi

Updated on June 12, 2022

Comments

  • titi
    titi almost 2 years

    I'm newbie to backbone.js and underscore.js.

    HTML :

    <div id="cartlist">
    <script type="text/template" id="cart_template">
    
    </script>
    </div>
    

    Where I called the view file :

    <script type="text/javascript" src="webcore/views/CartView.js"></script>
    </body>
    

    JS function(it works well with the javascript project):

     function Cart(){
        ......
        this.showCart = function (){
        var item = deserializeJSONToObj(window.localStorage.getItem(Cart.storageName));
        var str = '<table id="showcart">';
        str += '<tr><td class="cartitemhead">Item to buy</td><td class="cartitemhead" style="text-align: center;">Quantity</td></tr>';
        $.each(item, function(i, item) {
            str += '<tr><td><table class="verticallist"><tr><td rowspan="4" style="width: 120px;"><img src="' + item.PictureName + '" alt="Product" width="95px"/></td><td style="font-weight: bold;">'+trimString(item.Name,50)+'</td></tr><tr><td><i>Available in Stock(s)!</i></td></tr><tr><td><i>Rating:   650Va-390w Input:   Single</i></td></tr></table></td><td class="centertxt">'+item.QuantityInCart+'</td></tr>';
        });
        str += '</table>';
        return str;
     } 
    

    This is the Views :

    var myCart = new Cart();
    CartList = Backbone.View.extend({
    initialize:function(){
        this.render();
    },
    render: function(){
        var template = _.template( $("#cart_template").html(), {} );
        this.$el.html( template );
    }
    });
    var cart_view = new CartList({ el: $("#cartlist").html(myCart.showCart()) });
    
    1. when I trying to call the view template, I am getting error Uncaught TypeError: Cannot call method 'replace' of undefined - underscore.js. Please help me to find the mistake.

    2. How can I convert str string in Cart class to a template of underscore.js.

    Any help would be much appreciated, thank you.

  • titi
    titi over 10 years
    I tried to change <div id="cartlist"></div><script type="text/template" id="cart_template"/> but there nothing display in UI. And could you give me an example of your view should create its own el and the caller should put that el where it wants it in the DOM please. Thanks.
  • mu is too short
    mu is too short over 10 years
    But your template is empty so why would anything display? The Backbone documentation and the standard TODOs example should show you how to set up a view that creates its own el.
  • titi
    titi over 10 years
    It is working while I did this render: function(){ this.$el.html(myCart.showCart()); } and var cart_view = new CartList({ el: $("#cartlist") });.
  • ismnoiet
    ismnoiet over 9 years
    Put your backbone code inside the $(document).ready() method to insure that the DOM is ready so $('#cart_template') is accessible then the backbone code will be executed
  • mu is too short
    mu is too short over 9 years
    @hamism: Not in this case. The problem here is that the template is inside the DOM node that is the view's el, then the content of el is replaced and that destroys the DOM node that contains the template.