Adam
Adam

Reputation: 683

Coffeescript jQuery each loop

I'm relatively new to Coffeescript and am running into some issues that I think are to do with skinny arrow vs fat arrow / _this vs this vs $(this).

I have the following class and constructor:

class @scenarioEditPage
  constructor: ->
    @getParentAttributes()

and @getParentAttributes() is

getParentAttributes: ->
    @properties = {}
    $("#form_configurable").find('input[type=hidden]').each (index, element) =>
      @properties[$(element).attr('id')] = element.val()

Essentially what I'm trying to do is loop through all hidden fields in a form and assign their value to a key/value pair in the properties hash that can be used later. Example: hidden input field with id=some_id and value=some_value becomes properties[some_id] = some_value.

Any help would be greatly appreciated. Thank you!

Upvotes: 1

Views: 2218

Answers (1)

mrtn
mrtn

Reputation: 353

First of all, I wouldn't use class @scenariosEditPage unless you really have to. class ScenariosEditPage would be better.

Try something like this: http://jsfiddle.net/y6bgrfn2/

    class Test
        constructor: () ->
            @data = {}
            @loadData()

        loadData: ->
            $inputs = $("#container input").each (index, elem) =>
                $elem = $ elem
                @data[$elem.attr('id')] = $elem.val()

        getData: -> @data

    $(document).ready () ->
        test = new Test()
        console.log test.getData()

jQuery's each method changes the context of the inside code, so basically you have to use double arrow to preserve the context or simple arrow with with extra variable, for example ctx = @, check this:

    # We have some method @doAnything, so :
    @doAnything
    # isnt undefined...

    # Now:
    # this works
    $('selector...').each (index, elem) =>
        # @ == this == caller's context
        @doAnything $(elem)

    # or this works fine
    ctx = @
    $('selector...').each () ->
        # this == DOM Element
        # ctx == caller's context
        # ! ctx isnt @ !
        ctx.doAnything $(this)

    # this doesnt work
    $('selector...').each () =>
        # @ == DOM Element, so @doAnything is undefined
        @doAnything $(this)

And you have small bug in your code:

    @properties[$(element).attr('id')] = element.val()

element.val() is undefined, fix it like this:

    @properties[$(element).attr('id')] = $(element).val()

or better:

    $element = $ element
    @properties[$element.attr('id')] = $element.val()

Upvotes: 3

Related Questions