0

In the following code, I want to use the markers variable, which I expect to be an array of objects (e.g., [{...},{...},{...}]). However depending on the indentation level, the variable shows an empy array (i.e., []).

jQuery ->
  markers = []
  $.getJSON '/users.json', (data) ->
    for obj in data
      marker = {}
      marker =
        lastname: namify(obj.name)
        address: obj.address
      markers.push(marker)
    console.log("3rd level", markers) # It shows the array I want.
  console.log("2nd level", markers)   # "markers" shows an empty array.

My Expectation - populated array in the 2nd level. Result - an empty array in the 2nd level.

How can I retrive the array as shown in the 3rd level when I'm at the 2nd level.

2
  • In ECMAScript there are only two scopes: global and function. There are nested functions that have the activation object of outer functions on their scope chain, and closures that keep such scope chains in tact if the inner function persists after the outer function has exited. Dunno how that applies in the above CofffeeScript + jQuery + AJAX + JSON though. PS. What does the JSON look like? Commented Sep 13, 2011 at 5:36
  • The problem has nothing to do with scope. Notice that the console.log("2nd level") line runs before the console.log("3rd level") line, and see cenanozen's answer below. Commented Sep 13, 2011 at 14:23

1 Answer 1

4

You are populating your array inside the callback function. So it's populated after you print the result. Problem is not about scope, it is about order of execution.

If you make a synchronous request you should see what you expect:

jQuery ->
  markers = []
  $.ajax
    url: '/users.json'
    dataType: 'json'
    async: false
    success: (data) ->
      for obj in data
        marker = {}
        marker =
          lastname: namify(obj.name)
          address: obj.address
        markers.push(marker)
    console.log("3rd level", markers)
  console.log("2nd level", markers)
Sign up to request clarification or add additional context in comments.

2 Comments

Of course, as a practical matter, you really, really don't want to use async: false (which locks up the browser until the server responds). Just structure your app so execution continues from the success callback.
Yes, it's bad practice. I just wrote it this way for demonstration purpose.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.