A
A
Andrey Fedoseev2017-09-03 23:43:51
JavaScript
Andrey Fedoseev, 2017-09-03 23:43:51

How to make a promise work in a loop as it should?

There is data in the format:

let data = {
  "orders": [
    {
      "order_id": 1,
      "adres": "Москва-сити,первый красногвардейский проезд,16б"
    }, {
      "order_id": 2,
      "adres": "Подольск, мкр Климовск, по-кт 50-летия Октября, 10"
    }, {
      "order_id": 3,
      "adres": "г. Павловский Посад, 4-й Захаровский переулок, д. 6"
    }, {
      "order_id": 4,
      "adres": "волгоградский проспект, д1572"
    }
  ]
};

The task is to generate a map, place labels, click on the label to launch the gallery (photo on the server in a folder called %order_id% ).
ymaps.ready(() => {
  let myMap = new ymaps.Map("delivery-map", {
    center: [55.610906, 37.488429],
    zoom: 8
  });
  
  let myGroup = new ymaps.GeoObjectArray({}, {
    strokeWidth: 14,
    geodesic: true
  });
    
  for (let i in data.orders) {
    let id = data.orders[i].order_id;
    let location = data.orders[i].address;
    
    console.log(`${id}\t${location}`);

    ymaps.geocode(location, {
      results: 1
    }).then(r => {
      let c = r.geoObjects.get(0).geometry.getCoordinates(),  
      let p = new ymaps.Placemark(c, {
        iconContent: id,
        hintContent: location
      });
      
      console.log(`${id}\t${location}`);
      
      myGroup.add(p);
    });
  }
  
  myMap.geoObjects.add(myGroup);
});

Actually the question is: why is this happening and how to make it in the label
p = new ymaps.Placemark(c, { iconContent: id, hintContent: location });
the data of the current iteration was written (id is needed to launch the gallery).
https://jsfiddle.net/ygtke0kt/1/

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Stalker_RED, 2017-09-03
@itlen

Instead of var id use let id.

why is this happening
ymaps.Placemark works asynchronously.
By the time the first label is drawn, the var i in... loop has already completed its work and the last value from the loop remains in the id variable.
Read about "variable scope" and "closures".
If you need support for browsers that do not have let, then you can move the declaration of the id variable to the same place as "c".
(Although promises won't work in such browsers either, so this is a pure theorist :))

F
freeExec, 2017-09-04
@freeExec

It is enough to single out a separate function, where to pass the Order to the input, then you will not depend on i.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question