Nobody
Nobody

Reputation: 420

Uncaught ReferenceError: models is not defined in the html file in a backbone.js application

demo.js

var CommentsCollection = Backbone.Collection.extend({

    url : "http://0.0.0.0:8080/"

});

var CommentsListView = Backbone.View.extend({

    el: '.page',

    render : function(){
        var that = this;
        var commentsCollection = new CommentsCollection();
        commentsCollection.fetch({
            success: () => {
                    var models = commentsCollection.models;
                    // _.each(models, function(models){
                    //  console.log(models.get('firstname'));
                    // });

                  var template = _.template($('#reddit-comments-template').html());
                  that.$el.html(template(models));
            }
        })
    }
});


var PageRouter = Backbone.Router.extend({
    routes: {
        '' : 'home'
    }
});

Backbone.history.start();

index.html

<html>
<head>
    <title> </title>
</head>
<body>
    <div class="container">
        <h1>Top posts</h1>
        <hr />
        <div class="page"></div>
    </div>

    <script type="text/template" id="reddit-comments-template">
        <table class = "comments table">
            <thead>
                <tr>
                    <th>Row</th>
                    <th>Commments</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <% _.each(models, function(models){ %>
                    <tr>
                        <td><%= models.get('firstname') %></td>
                        <td><%= models.get('lastname') %></td>
                        <td><%= models.get('id') %></td>
                    </tr>
                    <% }); %>
                </tr>
            </tbody>
        </table>
    </script>

    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="underscore-min.js"></script>
    <script type="text/javascript" src="backbone-min.js"></script>
    <script type="text/javascript" src="demo.js"></script>

</body>
</html>

Actually if you see, I tried some getting some data from the api and updating the view according to the changes in the data, the collection gets the data from the api and then I get the models of the collection to loop over the data from the model, the variables in the models get printed in the log I added in the js script in the comments as you can see but I guess the value is not passed to the html file, giving rise to that error. Can you please tell me how to correct it.

Upvotes: -1

Views: 1935

Answers (2)

Rajat Badjatya
Rajat Badjatya

Reputation: 818

Before sending the collection or model to the template first serialize it with toJSON() method that is available on both Backbone's model and collection. When we use toJSON over a collection, it returns an array containing the attributes hash of each model.

var CommentsListView = Backbone.View.extend({
    el: '.page',
    // read and compile the template once
    template: _.template($('#reddit-comments-template').html()),

    render: function() {
        var commentsCollection = new CommentsCollection();
        commentsCollection.fetch({
            context: this, // avoids "that = this;"
            success: function(collection, response, options) {
                that.$el.html(this.template({ models: collection.toJSON() }));
            }
        });
    }
});

PS: I have added the default arguments in success callback.

Upvotes: 1

waranlogesh
waranlogesh

Reputation: 1004

You can convert the collection to json and pass it to template and access the models. In this way you can iterate through models using _.each and render their attributes in template.

var CommentsListView = Backbone.View.extend({

    el: '.page',

    render : function(){
        var context = {};
        this.commentsCollection = new CommentsCollection();
        this.commentsCollection.fetch({
            success: () => {
                    //var models = commentsCollection.models;
                    // _.each(models, function(models){
                    //  console.log(models.get('firstname'));
                    // });
                  context['models'] = this.commentsCollection.toJSON()
                  var template = _.template($('#reddit-comments-template').html());
                  that.$el.html(template(context));
            }
        })
    }
});

Template:

<html>
<head>
    <title> </title>
</head>
<body>
    <div class="container">
        <h1>Top posts</h1>
        <hr />
        <div class="page"></div>
    </div>

    <script type="text/template" id="reddit-comments-template">
        <table class = "comments table">
            <thead>
                <tr>
                    <th>Row</th>
                    <th>Commments</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <% _.each(models, function(model){ %>
                    <tr>
                        <td><%= model.firstname %>
                        <td><%= model.lastname %></td>
                        <td><%= model.id %></td>
                    </tr>
                    <% }); %>
                </tr>
            </tbody>
        </table>
    </script>

    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="underscore-min.js"></script>
    <script type="text/javascript" src="backbone-min.js"></script>
    <script type="text/javascript" src="demo.js"></script>

</body>
</html>

Upvotes: 2

Related Questions