0
votes

I have a backbone view that has a single click event to update a collection. In my console, I can see the object being updated and the number of models being returned is changing, however the view stays static after the event is fired for the first time and any second attempt to fire it gives me the error TypeError: text is undefined. For reference, I have my script loading at the bottom of the page and the template (using underscore) is above it.

Here's my view

app.MyView = Backbone.View.extend({
el: 'body',
events: {
    'click #submit': 'fetchData'
},
initialize: function() {

    this.collection = new app.MyCollection();

    // On my first attempt, I tried having a the render tied to the sync event when the view initiated, although the sync event doesn't actually occur until something is clicked
    // this.collection.on('sync', this.render, this);
},
render: function() {
    console.log('rendering');

    var schedule = $('#schedule');
    var template = _.template($('#times-template').html());
    schedule.html(template({ collection: this.collection.toJSON() }));
},
fetchData: function() {

    that = this;

    stationQuery.station_start      = $('#start').val();
    stationQuery.station_end        = $('#end').val();

    var query = stationQuery;

    this.collection.fetch({
        data: query,
        success: function(collection, response) {
            console.log('fetching data');
            console.log(collection);

            // attempt #2 - moving the sync event to the success callback of fetch doesnt allow the view to update a second time either
            // collection.on('sync', that.render, that);

        },
        error: function(collection, response) {
            console.log('error on fetch', response);
        }
    });
},
});

app.myView = new app.MyView;

// Third attempt, this time checking if listenTo will allow the view to update every time the event is fired. It still only works on the first time and fails to render for consecutive clicks, even though the console is showing updated models
app.myView.listenTo(app.myView.collection, 'sync', app.myView.render);
1

1 Answers

0
votes

Below is a working code, I just added initial call to fetch data at the end

app.myView.fetchData();

And uncommented your .on('sync', ... inside initialize

this.collection.on('sync', this.render, this);

I tested it with jsbin so you can see what's was wrong for you. As a result I see initial rendering of fetched data and clicking the #submit will re-fetch and re-render view.

app.MyView = Backbone.View.extend({
el: 'body',
events: {
    'click #submit': 'fetchData'
},
initialize: function() {

    this.collection = new app.MyCollection();

    // Here is a binding to each fetch data and on success render view
    this.collection.on('sync', this.render, this);
},
render: function() {
    console.log('rendering');

    var schedule = $('#schedule');
    var template = _.template($('#times-template').html());
    schedule.html(template({ collection: this.collection.toJSON() }));
},
fetchData: function() {

    that = this;
    var stationQuery = {};
    stationQuery.station_start      = $('#start').val();
    stationQuery.station_end        = $('#end').val();

    var query = stationQuery;

    this.collection.fetch({
        data: query,
        success: function(collection, response) {
            console.log('fetching data');
        },
        error: function(collection, response) {
            console.log('error on fetch', response);
        }
    });
},
});

app.myView = new app.MyView;

// Here is first call to fetch data and on success render view
app.myView.fetchData();