rui
rui

Reputation: 115

coffeescript accessing instance variable

im somewhat new to js or coffeescript and i cant figure out what is wrong with my script.

class Token

  fetching_token = $.Deferred()
  assigning_token = $.Deferred()

  constructor: ->
    @token = null
    @got_token = $.Deferred()    

  fetch = ->
    fetching_token.resolve({"access_token": '12355'})

  assign_token = (data) =>
    console.log "TOKEN (instance var): " + @token #undefined? 
    @token = data.access_token
    assigning_token.resolve()

  get_token: ->
    fetch()
    $.when(fetching_token).done (data) =>
      assign_token(data)
    $.when(assigning_token).done =>
      @got_token.resolve()
    undefined


t = new Token
t.get_token()

$.when(t.got_token).done ->
  console.log "FETCHED TOKEN: " + t.token #gives null

Im trying to expose following interface on instance of object: token, got_token, get_token. For some reason the @token in assign_token is undefined. I tried some combinations with fat arrow but couldnt make it to work. Thank you in advance

Upvotes: 0

Views: 976

Answers (1)

mu is too short
mu is too short

Reputation: 434985

This is a simple (private) function, not a method:

f = (arg) -> ...

This is a private function that is bound to the class:

f = (arg) => ...

The => binds the function to whatever @ (AKA this) is when the function is defined. When you say this:

class C
    f = (arg) => ...

@ is the class C when f is being parsed so f is sort of a private class method.

The important thing is that when you say this:

assign_token = (data) =>
  #...

@ inside assign_token will not be an instance of Token, it will actually be Token itself. Your @token is an instance variable on instances of Token so of course it isn't defined when you don't have an instance of Token in @.

You have a couple options:

  1. Make assign_token an instance method. This makes assign_token publicly accessible.
  2. Force the @ issue using call or apply. This keeps assign_token private but more cumbersome to call.

The first option looks like this:

assign_token: (data) ->
    # Same stuff you already have

The second on is (mostly) done when you call assign_token:

assign_token = (data) ->
    # Same stuff you already have

get_token: ->
  fetch()
  $.when(fetching_token).done (data) =>
    assign_token.call(@, data)
  #...

Note the skinny arrow (->) when defining assign_token, that gives you a simple function so that you can set the desired @ when you call it with the function's call method.

Upvotes: 2

Related Questions