-1

Context of my problem :

I am trying to create an array of the google maps Longitude and Latitudes to use in a heatmap. I am able to get data from my localhost and want to be able to reference an array that I create within the subscribe function outside of the function.

When I console.log a all of my data it comes out perfectly. When I try to reference the this.heatmapData outside of the subscribe function it is empty.

Here is the code

    this.result = this.examsApi.getExams()
        .subscribe(data => {
          this.examsList = data;
          this.i=0;
          var obj = JSON.parse(data);
          var val;
          this.heatmapData = [];
          for (val in obj["index"]) {
            console.log(this.heatmapData) // Fills perfectly
            this.heatmapData.push(new google.maps.LatLng(obj["Latitude"][val], obj["Longitude"][val])); // The parameters are filled with longitude and latitude values a http.get request in another file.
      } 
        });
    console.log(this.heatmapData) // Becomes empty
Antoniossss
  • 31,590
  • 6
  • 57
  • 99
Enesxg
  • 127
  • 4
  • 13
  • 2
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Igor Aug 07 '18 at 22:29

1 Answers1

3

It does not become empty but it is empty at the moment of logging, you log it into the console, and then you fetch the data - subscribe is async!

Order of execution:

  1. Create cold observable by this.examsApi.getExams()
  2. Heat it up by subscribing to it - AJAX request is STARTED
  3. console.log(this.heatmapData) // prints empty array because IT IS EMPTY NOW
  4. IO delay
  5. AJAX FINISHES - Response comes, subscription callback is called - you push data to this.heatmapData

I can only assume that you see no update on UI. This is because you are pushing to the array - Angular will not detect such change by itself. Either you have to invoce change detection run, or better, create new array, but data to it, and replace the array by assigning this.heatmapData=yourNewArrayOfData

and want to be able to reference an array that I create within the subscribe function outside of the function.

Looks like I got to the point here - build new array and assign it to this.heatmapData insteed of pushing. Angular will detect that change.

Since some people finds this answer "not an answer at all" i must include copy-pasted code I guess.

   this.result = this.examsApi.getExams()
            .subscribe(data => {
              this.examsList = data;
              this.i=0;
              var obj = JSON.parse(data);
              var val;
              const newData= [];
              for (val in obj["index"]) {
                newData.push(new google.maps.LatLng(obj["Latitude"][val], obj["Longitude"][val])); // The parameters are filled with longitude and latitude values a http.get request in another file.
          } 
          this.heatmapData=newData; // this will do the trick
          console.log(this.heatmapData); // this will print just fine
            });
Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • Explanation what is happening is the solution to all OPs problems here - not only ths particular one, but any similar issue he will face when debuging async code in the future. – Antoniossss Aug 07 '18 at 22:16
  • Thanks Antonios. This helped me realize the concept. You can't globalize or make public outside of the subscribe function any of the "this." variables – Enesxg Aug 07 '18 at 22:59