Roeland
Roeland

Reputation: 3858

Callback on asynchronous request , passed variables get overwritten when I dont want them to

I am currently looping through an array of location objects. I am then calling out to google to get me a panorama for that location. The problem is the request for this is asynchronous, so when the callback actually gets called, the location variable I passed is the last location in the array.

Here is example code, and console log output:

  for location in paginated_data.locations
    console.log location
    latLng = new google.maps.LatLng(location.latitude,location.longitude)
    @sv.getPanoramaByLocation(latLng, 50, (StreetViewPanoramaData, StreetViewStatus) =>
      console.log location          
    )

enter image description here

As you can see, in the initial loop the console sees the correct location, in the callback, it only shows the last one from the loop. Can anyone point me in the right direction on how to fix this?

Upvotes: 0

Views: 184

Answers (1)

go-oleg
go-oleg

Reputation: 19480

UPDATE:

You should use the do keyword to have coffeescript create a separate closure for each loop iteration:

  for location in paginated_data.locations
    do (location) ->
      console.log location
      latLng = new google.maps.LatLng(location.latitude,location.longitude)
      @sv.getPanoramaByLocation(latLng, 50, (StreetViewPanoramaData, StreetViewStatus) =>
        console.log location

ORIGINAL (the not-so-coffeescript but still in coffeescript way of doing it):

You need to wrap your code in an iife so that it has its own scope and pass in location:

  for location in paginated_data.locations
    ((location) ->
      console.log location
      latLng = new google.maps.LatLng(location.latitude,location.longitude)
      @sv.getPanoramaByLocation(latLng, 50, (StreetViewPanoramaData, StreetViewStatus) =>
        console.log location          
      )(location)

or move the body of the for loop into a separate function

  getLocation = (location) ->
    console.log location
    latLng = new google.maps.LatLng(location.latitude,location.longitude)
    @sv.getPanoramaByLocation(latLng, 50, (StreetViewPanoramaData, StreetViewStatus) =>
       console.log location

  for location in paginated_data.locations
    getLocation(location)

Upvotes: 3

Related Questions