Alessandro Macanha
Alessandro Macanha

Reputation: 711

Function is ignored and only trigger at the end of map

I'm having some problems with my function, the problem is all the Establishment.finById() is ignored until the end of the map, I need that findById for every item that enters on if. At the end of the map, finById fires, but only occurs on the last map object. I can work around the problem using another map, but I do not want to do this. I think the problem is something related to async / wait, but I can not figure out what is.

try{
    Logger.log("Info", "Buscando estabelecimentos na API.");
    const url = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=' + latitude + ',' + longitude + '&radius=200&type=store&key=' + GOOGLE_PLAY_API;
    axios.get(url).then(response => {
        let resultados = response.data.results;
        if(resultados.length == 0) {
            Logger.log("Info", "Nenhum resultado encontrado pela API");
            return resposta.status(404).send("Nenhum resultado encontrado pela API");
        } else {
            resultados.map((item, i) => {
                let found = item.types.some(r => tipos_estabelecimentos.indexOf(r) >= 0);
                if(found){
                    var _estabelecimento = new Estabelecimento({
                        _id: item.place_id,
                        nome: item.name,
                        localizacao: { type: "Point", coordinates: [item.geometry.location.lng, item.geometry.location.lat]}
                    });
                    Estabelecimento.findById(_estabelecimento._id).then((result) => {
                        if(!result || result.length == 0){
                            _estabelecimento.save().then((success) => {         
                                Logger.log("Info", "Cadastrando novo estabelecimento: " + success);
                                listaEstabelecimentos.push(success);
                            }).catch((error) => {
                                if(error){
                                    Logger.log("Erro", "Erro ao cadastrar estabelecimento " + error);
                                }
                            });
                        } else {
                            Logger.log("Info",  "Estabelecimento " + _estabelecimento.name + " já cadastrado. Pulando...");
                        }
                    });
                }
            });
        }
        return resposta.status(200).send(listaEstabelecimentos);
    }).catch(error => {
        return resposta.status(500).send(error);
    }); 
} catch(error) {
    console.log(error);
}

Upvotes: 1

Views: 50

Answers (1)

Tholle
Tholle

Reputation: 112867

You are right in that it's an issue with findById being asynchronous. If you store all these asynchronous promises in an array and wait for them to finish with Promise.all before you send the listaEstabelecimentos, it will work as expected.

const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude},${latitude}&radius=200&type=store&key=${GOOGLE_PLAY_API}`;
const listaEstabelecimentos = [];

axios
  .get(url)
  .then(response => {
    let resultados = response.data.results;
    const promises = [];
    if (resultados.length == 0) {
      return resposta.status(404).send("Nenhum resultado encontrado pela API");
    } else {
      resultados.forEach((item, i) => {
        let found = item.types.some(
          r => tipos_estabelecimentos.indexOf(r) >= 0
        );
        if (found) {
          var _estabelecimento = new Estabelecimento({
            _id: item.place_id,
            nome: item.name,
            localizacao: {
              type: "Point",
              coordinates: [
                item.geometry.location.lng,
                item.geometry.location.lat
              ]
            }
          });
          promises.push(
            Estabelecimento.findById(_estabelecimento._id).then(result => {
              if (!result || result.length == 0) {
                _estabelecimento
                  .save()
                  .then(success => {
                    Logger.log(
                      "Info",
                      "Cadastrando novo estabelecimento: " + success
                    );
                    listaEstabelecimentos.push(success);
                  })
                  .catch(error => {
                    if (error) {
                      Logger.log(
                        "Erro",
                        "Erro ao cadastrar estabelecimento " + error
                      );
                    }
                  });
              } else {
                Logger.log(
                  "Info",
                  "Estabelecimento " +
                    _estabelecimento.name +
                    " já cadastrado. Pulando..."
                );
              }
            })
          );
        }
      });
    }
    return Promise.all(promises).then(() => {
      return resposta.status(200).send(listaEstabelecimentos);
    });
  })
  .catch(error => {
    return resposta.status(500).send(error);
  });

Upvotes: 2

Related Questions