explainer
explainer

Reputation: 1335

Uncaught type error with CoffeeScript and Backbone.js

Rails app, learning CoffeeScript and Backbone.js:

Uncaught TypeError: Cannot use 'in' operator to search for 'id' in easy
_.extend.setbackbone.js:205
Backbone.Modelbackbone.js:142
Gamegames.js:13
(anonymous function)games.js:34
jQuery.Callbacks.firejquery.js:1047
jQuery.Callbacks.self.fireWithjquery.js:1165
jQuery.extend.readyjquery.js:436
DOMContentLoadedjquery.js:924

Here is the code, games.js.coffee

jQuery ->
  root = global ? window
  class Game extends Backbone.Model
    initialize: (@n, @diff) ->
      console.log "--> Game.initialize()"
    difficulty: ->
      @diff
    name: ->
      @n
  # Make class Game globally available
  root.Game = Game
  my_game = new Game('easy', 'hard')
  console.log "my_game.name(), my_game.difficulty() --> #{my_game.name()}, #  {my_game.difficulty()}"

I am missing something, but having trouble figuring out what...

Upvotes: 0

Views: 407

Answers (1)

Alex Wayne
Alex Wayne

Reputation: 187004

Backbone model constructor functions expect a dictionary object with keys and values that will be set on that model. You didn't provide an object, and instead provided 2 strings. The error is cause by backbone trying to iterate through the object, but explodes because you can't legally do for (key in "easy").

You also shouldn't be using properties for model data. You should be using an object on instantiation or set() and get(). So, if I may correct your code:

jQuery ->
  root = global ? window
  class Game extends Backbone.Model
    initialize: ->
      console.log "--> Game.initialize()"
    difficulty: ->
      @get 'diff'
    name: ->
      @get 'n'
  # Make class Game globally available
  root.Game = Game
  my_game = new Game n: 'easy', diff: 'hard'
  console.log "my_game.name(), my_game.difficulty() --> #{my_game.name()}, #{my_game.difficulty()}"

See this example working here: http://jsfiddle.net/NMkna/

Note how we no longer accept arguments in initialize now. We can rely on backbone to set the proper attributes in the model, because we now pass in an object when creating the game. And the methods we define simply @get 'propname' in order to retrieve those values.

Upvotes: 2

Related Questions