Search code examples
javascriptjsonbackbone.jsmodel

Backbone.js fetch() JSON to model get() returns undefined


Basically I want to fetch a JSON file and store it in a model. However, when I try to access the attributes via get() it returns undefined. So lets say the JSON file has an array games that consists of objects with some attributes. It doesn't really matter. Just want to save them in the model and access them. So I'm doing something like this.

var player = Backbone.Model.extend({
   initialize: function(app, options) {
      this.app = app;
      var _this = this;

      this.fetch({
         url: "someurl",
         success: function() {
            console.log("success");
         }
      });
   }
});

var instplayer = new player();
instplayer.on('change', function(){
   console.log(model);
   console.log(model.get(games));
})

So I figured that I need an event to ensure that get() is called when the data is really available. But this still returns undefined. What do I need to do?


Solution

  • So I imagined you have a json for your player like this (I've mocked it here for the example below to work):

    {
        "username": "joe",
        "games": [
            {
                "title": "Pacman"
            }, {
                "title": "Super Mario" } 
        ]
    }
    

    And here's a complete working example of how I would deal with managing and rendering this kind of data:

    var Game = Backbone.Model.extend({
      defaults: {
        title: ''
      }
    });
    
    var Games = Backbone.Collection.extend({
      model: Game
    });
    
    var Player = Backbone.Model.extend({
      defaults: {
        username: ''
      },
      url: 'http://www.mocky.io/v2/56261127250000a01accb34f',
      initialize: function(){
        this.games = new Games();
        this.listenTo( this, "sync", this.initGames );
        this.fetch();
      },
      initGames: function(){
        this.games.add( this.get('games') );
        this.trigger('ready', this);
      }
    });
    
    var PlayerView = Backbone.View.extend({
      template: _.template('<h1><%=username%></h1> and his games: <ol class="games"></ol>'),
      render: function(){
        this.$el.html( this.template( this.model.toJSON() ) );
        this.model.games.each( this.renderGame, this );
        return this;
      },
      renderGame: function(game, i){
        var gameView = new GameView({ model: game });
        gameView.render().$el.appendTo( this.$('.games') );
      }
    });
    
    var GameView = Backbone.View.extend({
      tagName: 'li',
      template: _.template('<strong>Game:</strong> <%=title%>'),
      render: function(){
        this.$el.html( this.template( this.model.toJSON() ));
        return this;
      }
    });
    
    
    var dude = new Player();
    dude.on('ready', function(player){
      var playerView = new PlayerView({ model: player });
      playerView.render().$el.appendTo( document.body );
    });
    <script src='http://code.jquery.com/jquery.js'></script>
    <script src='http://underscorejs.org/underscore.js'></script>
    <script src='http://backbonejs.org/backbone.js'></script>