1

I have a list of office ids in an array. I loop through that array and use HTTP request services to get a name associated with the id. It passes back a promise which I learned that I have to use .then to unwrap it.

this.officeID = [100, 200, 300];
this.offices = [];

for (x in this.officeID) {
   OfficeService.getOfficeName(x).then(function (data) {
       this.offices.push([data, x]);
   });
};

The result that I desire is

[["Office1", 100], ["Office2", 200], ["Office3", 300]];

but what I got back was

[["Office1", 300], ["Office2", 300], ["Office3", 300]];

It seems like the service call is waiting for everything to get passed in to finish.

Graham
  • 7,431
  • 18
  • 59
  • 84
Jason Chen
  • 11
  • 3
  • Are these offices coming back as a stream? If that's the case you could create an observable from the `officeID` array and use the [`zip`](http://reactivex.io/documentation/operators/zip.html) operator to merge them together – 0mpurdy Aug 05 '17 at 22:58
  • 1
    Look into [Promise.all](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all). And also this question https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – elclanrs Aug 05 '17 at 22:59
  • The `for` loop completes before the asynchronous requests do, so by the time the `.push()` statements run `x` is `300`. – nnnnnn Aug 05 '17 at 23:00
  • @elclanrs is absolutely right, but I also wanted to add that using ES6's `let` also solves this issue, as x will have the value according to the scope, i.e. you can also use `for (let x in this.officeID)` – Gershon Papi Aug 05 '17 at 23:02
  • 1
    @GershonPapi - Note that IE didn't implement `let` properly, so in that browser only you'd need to put `let y = x` (or whatever variable name) inside the `{}` block for it to fix the problem. That is, in IE `let` variables defined inside the `{}` brackets work as expected, but those inside the `for(...)` part don't. – nnnnnn Aug 05 '17 at 23:06

0 Answers0