1

I can't figure out what is wrong with my code. It seems to be a javascript issue.

I'm loading a local txt file using $http.get (is there a different way?). I want to push this content into an array. For the sake of testing, I'm just pushing any string just to be sure that it doesn't have to do with the actual txt file.

 var myArray = [];
 $http.get(localFilePath).then(
        function(success){
            myArray.push("123");
        },
        function(error){
            // other stuff
        });

console.log(myArray);

This simple code will not generate a proper array. Here's a screenshot from Chrome dev tool if I console.log the array created:

enter image description here

Now, this looks like a proper array but it's not. If I console.log(myArray.length) it returns 0.

Here's instead how a proper array should look like using the same code myArray.push("123") outside $http.get() function:

enter image description here

Can someone tell what is the difference between the 2 arrays and why the first one is created differently if I do it inside $http.get() function?

Sergio
  • 250
  • 1
  • 4
  • 18
  • Can you show where you're console logging the array? Is it inside the success function or outside? – Soviut Jan 24 '19 at 18:20
  • 1
    @Soviut I'm console logging outside the success function – Sergio Jan 24 '19 at 18:23
  • you should edit your question and include that since it's critical to the answers we've given. – Soviut Jan 24 '19 at 18:29
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Jared Smith Jan 24 '19 at 18:52

3 Answers3

2

Because you are console.logging before the array gets the value most likely, and inside the console, chrome updates the array (since it's a reference) but not the length (since it's a primitive). Which is why as part of the array you can see the length property set properly. If you do:

var myArray = [];
let $http = { get: () => {
    var p = new Promise((resolve, reject) => {
        setTimeout(() => resolve('hi'), 1000);
    })
    return p;
}}
 $http.get('').then(
  function(success){
      myArray.push("123");
      console.log(myArray, myArray.length, 'after');
  },
  function(error){
      // other stuff
  }
);
console.log(myArray, myArray.length, 'before');

You can see what I mean.

dave
  • 62,300
  • 5
  • 72
  • 93
  • I'm struggling to understand the first part of your code. How can I edit my code so that when I console log outside of the function the array is ready? – Sergio Jan 24 '19 at 19:43
  • You wait until it's ready - use `.then` or pass in a callback – dave Jan 24 '19 at 19:52
2

This is an asynchronous issue. You're calling console.log() outside the promise's "resolve" function.

var myArray = []
$http.get(localFilePath).then(function(result) {
  myArray.push("123")
})

// outside resolve function     
console.log(myArray)

Since this is an asynchronous operation, that resolve function is only called once the $http.get() request finishes (usually a few hundred milliseconds later). However, it does NOT wait, so the rest of the code continues to run. So it kicks off the get(), then immediately runs the console.log() before the http request has had a chance to finish so it hasn't populated the array by the time console.log() is called.

If you were to put the console.log() inside the resolve function, you'd see the array was correctly populated because it waited for the http request to finish, populated the array, and only then did it print the result.

$http.get(localFilePath).then(function(result) {
  myArray.push("123")

  // inside resolve function     
  console.log(myArray)
})
Soviut
  • 88,194
  • 49
  • 192
  • 260
0

I have understand your problem and tried below code and I am getting same array this is correct. your are assigning pushing an object returning from service instead of array.Array.push() will work same with in $http.get() service and out side $http.get() service

  var myArray = [];
  $http.get(localFilePath).then(
    function(success){
        myArray.push("123");
       return success
    },
    function(error){
        // other stuff
     return success
    });

  console.log(myArray);
  var myArray2 = [];
  myArray2.push("123");
  console.log(myArray2);
Sunil
  • 138
  • 2
  • 15