Jordi Salom
Jordi Salom

Reputation: 121

backbone Cannot read property 'push' of undefined

i'm working with Backbone and when I generate the view I have the error Cannot read property 'push' of undefined". The line of the error is "self.subViewsReservas.push(new ReservaView({" in the push.

    ReservaCollectionView = Backbone.View.extend({

initialize: function () {
    if (Session.get('authenticated') && Session.get('authenticated') !== false) {
        this.paginacionVista = new PaginacionReservasView({
            collection: this.collection,
            el: '.paginacionReservas',
            reservasPagina: 5,
        });
        this.buscadorVista = new BuscadorView({
            el: 'div.buscador-reservas',
            //Pasamos la colección oficinas ya que hará las veces del conjunto de oficinas retornadas por el servidor
            collection: new OficinasCollection(oficinas),
        });
    }
    else {
    }
},
render: function () {
    var self = this;
    this.template = _.template($('#divReservaTpl').html(), {});
    self.$('.contenedor-reservas').empty();
    self.collection.each(function (reserva, index) {
        self.$('.contenedor-reservas').append(self.template({'data': reserva.toJSON()}));
    });
    this.collection.each(function (reserva, index) {
      this.subViewsReservas = [];
          self.subViewsReservas.push(new ReservaView({
              el: '#' + reserva.get('Idreserva'),
              model: reserva
          }));
    });
    this.collection.each(function (reserva, index) {
        //Limite de la paginacion 5 limite arbitrario
        if (index < 5) {
            //Lo Marcamos como visible y actualiazamos la paginación
            self.collection.get(reserva.get('Idreserva')).set({'Visibilidad': true});
        }
    });

    this.paginacionVista.render();

    return this;
},

});

AppView = Backbone.View.extend({
    initialize : function(){
            var self = this;

            self.usu = new UsuarioModel();
            self.usu.fetch({
                success: function (model){
                    Session.fetch({
                        success : function (){

                            Session.set('nombre',model.get('Nombre'));
                            Session.set('apellidos',model.get('Apellidos'));
                            Session.set('puntos_club',model.get('Puntosclub'));

                            self.render();
                        }
                    });

                    self.sideBar = new SideBarView({
                        el : '.sidebar',
                        model: model
                    });
                    self.sideBar.markOption('mis-reservas');
            AppView = Backbone.View.extend({
    initialize : function(){
            var self = this;

            self.usu = new UsuarioModel();
            self.usu.fetch({
                success: function (model){
                    Session.fetch({
                        success : function (){

                            Session.set('nombre',model.get('Nombre'));
                            Session.set('apellidos',model.get('Apellidos'));
                            Session.set('puntos_club',model.get('Puntosclub'));

                            self.render();
                        }
                    });

                    self.sideBar = new SideBarView({
                        el : '.sidebar',
                        model: model
                    });
                    self.sideBar.markOption('mis-reservas');
                },
                error : function (){
                    document.location = '/mygoldcar/login';
                }
            });            

            this.listenTo(Session, 'change', self.update);        
    },
    render : function(){
            var self = this;
            var reservas = new ReservasCollection();
            reservas.fetch({
                success: function (collection){
                    if ( typeof collection.models[0].get('error') == 'undefined' || !collection.models[0].get('error')) {
                        var listRes = new ReservaCollectionView({
                            el : '.reservas-list',
                            collection: collection   
                        });
                        listRes.render();

                        var popoverModel = new Popover();
                        popoverModel.setData(collection.models[0].get('kilometraje_ilimitado'), collection.models[0].get('duracion'));

                        self.popover = new PopoverView({
                            el: 'body',
                            model: popoverModel
                        });

                        self.popover.establecerPopover();
                    }
                    else document.location = '/mygoldcar' + self.urlLang(lang) + '/mi-cuenta/#msg/1';                    
                },
                error: function () {
                    document.location = '/mygoldcar' + self.urlLang(lang) + '/mi-cuenta/#msg/1';                    
                }
            });
    },
        update: function() {
            var self = this;
            self.sideBar.update(Session.get('nombre'),Session.get('apellidos'),Session.get('puntos_club'));   
            self.$el.find('.nombre-usuario').text(Session.get('nombre'));            
        },
        updatePoints: function() {
            var self = this;
            self.usu.fetch({
                success: function (model){
                    Session.set('puntos_club',model.get('Puntosclub'));
                }
            });
        }   
});    },
                error : function (){
                    document.location = '/mygoldcar/login';
                }
            });            

            this.listenTo(Session, 'change', self.update);        
    },
    render : function(){
            var self = this;
            var reservas = new ReservasCollection();
            reservas.fetch({
                success: function (collection){
                    if ( typeof collection.models[0].get('error') == 'undefined' || !collection.models[0].get('error')) {
                        var listRes = new ReservaCollectionView({
                            el : '.reservas-list',
                            collection: collection   
                        });
                        listRes.render();

                        var popoverModel = new Popover();
                        popoverModel.setData(collection.models[0].get('kilometraje_ilimitado'), collection.models[0].get('duracion'));

                        self.popover = new PopoverView({
                            el: 'body',
                            model: popoverModel
                        });

                        self.popover.establecerPopover();
                    }
                    else document.location = '/mygoldcar' + self.urlLang(lang) + '/mi-cuenta/#msg/1';                    
                },
                error: function () {
                    document.location = '/mygoldcar' + self.urlLang(lang) + '/mi-cuenta/#msg/1';                    
                }
            });
    },
        update: function() {
            var self = this;
            self.sideBar.update(Session.get('nombre'),Session.get('apellidos'),Session.get('puntos_club'));   
            self.$el.find('.nombre-usuario').text(Session.get('nombre'));            
        },
        updatePoints: function() {
            var self = this;
            self.usu.fetch({
                success: function (model){
                    Session.set('puntos_club',model.get('Puntosclub'));
                }
            });
        }   
});

Upvotes: 0

Views: 194

Answers (1)

T J
T J

Reputation: 43156

Inside collection.each, this points to the collection. So the property subViewsReservas is added to it, not the view instance. When you try to access it like self.subViewsReservas.push, self points to the view instance, which doesn't have subViewsReservas property, hence the error.

Initializing an array inside each like you're doing isn't doing much since it'll be reset with each invocation of the callback.

You should be initializing it in the initialize method, which is the right place to initialize things, where this will correctly point to the view instance as shown below

initialize: function () {
  this.subViewsReservas = [];
}

For some reason if you want the collection to reset everytime, you can change the context to view by passing it as second argument to each like:

this.collection.each(function (reserva, index) {
  this.subViewsReservas = [];
      self.subViewsReservas.push(new ReservaView({
          el: '#' + reserva.get('Idreserva'),
          model: reserva
      }));
}, self); // <--- makes view the context of callback,
          // both 'self' and 'this' will refer to view

Upvotes: 1

Related Questions