rai
rai

Reputation: 68

CoffeeScript prototype error

Here's an example of what I'm trying to do.

User = (name,dob,rank,score) -> 
    {
        name: name
        dob: dob
        details: {
            rank: rank
            score:score 
        }

        basicInfo: -> return "Name: #{@name} - Dob: #{@dob} - #{@details.rank} "
        detailedInfo: -> return "Name: #{@name} - Rank: #{@details.rank} - Score: #{@details.score}"
    }

User::displayName = ->
    console.log @name 

bob = new User("Bob","10/12/69",1,100000)

bob.displayName()

I'm getting an error that says "Uncaught TypeError: Object # has no method 'displayName'"

Not really sure why I'm getting this error. Any help is greatly appreciated.

Upvotes: 5

Views: 253

Answers (2)

Ricardo Tomasi
Ricardo Tomasi

Reputation: 35253

When you return a new object from the constructor, it doesn't share the prototype. A proper constructor adds properties/methods to this:

User = (name,dob,rank,score) -> 
  @name = name
  @dob = dob
  @details =
    rank: rank
    score: score 
  @basicInfo = -> return "Name: #{@name} - Dob: #{@dob} - #{@details.rank} "
  @detailedInfo = -> return "Name: #{@name} - Rank: #{@details.rank} - Score: #{@details.score}"

You might want to take advantage of CoffeeScript's class abstraction, which just generates standard constructor functions:

class User
  constructor: (name, dob, rank, score) ->
    @name = name
    @dob = dob
    @details:
      rank: rank
      score: score 
  basicInfo: ->
    return "Name: #{@name} - Dob: #{@dob} - #{@details.rank} "
  detailedInfo: ->
    return "Name: #{@name} - Rank: #{@details.rank} - Score: #{@details.score}"

This is functionally the same as above, except that basicInfo and detailedInfo here are already in the prototype, where they should be. With this, User::displayName = -> console.log @name should work fine.

See http://coffeescript.org/#classes

Upvotes: 4

Florian Margaine
Florian Margaine

Reputation: 60717

You're trying to copy javascript in coffeescript. Badly. (By mixing static methods and prototype methods.)

In CoffeeScript, you can use the keyword class to do what you want.

class User
    constructor: (@name, @dob) ->

    displayName: ->
        console.log @name

bob = new User "Bob", "10/12/69"

bob.displayName() // "Bob"

More information: http://coffeescript.org/#classes

Upvotes: 4

Related Questions