Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 552
rai Avatar asked Jul 04 '12 14:07

rai


2 Answers

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

like image 140
Ricardo Tomasi Avatar answered Sep 20 '22 01:09

Ricardo Tomasi


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

like image 20
Florian Margaine Avatar answered Sep 21 '22 01:09

Florian Margaine