0

I am generating an image from google map. This is a promise return method in that I am just looping with the results and storing the result into a new Array variable inside the "then" callback but the response is there but it's not showing in the browser.

Before my google map generating images function was not a promise return function and it was sending the response to browser but it's a promise return function so the response is there but the controller method is not sending a response to the browser.

  static providerMapImageGenerator(req, res) {
    let providerArr = []
    ProvidersRepository.getProviderInfoForMapImage()
      .then(providers => {
        providers.forEach(provider => {
          // Generating image against each entr
          MapGenerator.getMapImage(
            provider.latitude,
            provider.longitude,
            provider.name,
            provider.providerId
          )
            .then(res => {
              // Saving record after each entry
              ProviderMap.create({
                providerId: provider.providerId,
                url: res.Location
              })
              // Adding new array for response
              providerArr.push({
                id: provider.providerId,
                url: res.Location,
                lat: provider.latitude,
                long: provider.longitude,
                name: provider.name
              })
            })
            .catch(err => console.log(err, "err in generating image"))
        })
        // Sending final response against all generated entries to user
        res.send(providerArr) // this is going blank to the browser
      })
      .catch(error => {
        // Sending error response if fails
        res.send(error)
      })
  }

I need the providerArr response to display in the browser.

3
  • 2
    For loops do not wait for async actions to finish before continuing on to the next iteration. Use Promise.all and pass it an array of promises to wait for them all to complete Commented Jun 25, 2019 at 16:12
  • how I can resolve this? Commented Jun 25, 2019 at 16:13
  • @IsaacVidrine Can you please tell me how to add promise.all in my current code. Thank you. Commented Jun 25, 2019 at 16:17

2 Answers 2

1

Your loop is going without waiting for promise result. You can use async/await with for of loop to do what you want as below:

ProvidersRepository.getProviderInfoForMapImage()
  .then(async (providers) => {
    for(provider of providers){
      // Generating image against each entr
      let image = await MapGenerator.getMapImage(
        provider.latitude,
        provider.longitude,
        provider.name,
        provider.providerId
      );
      // Saving record after each entry
      await ProviderMap.create({
         providerId: provider.providerId,
         url: res.Location
      });
       // Adding new array for response
      providerArr.push({
          id: provider.providerId,
          url: res.Location,
          lat: provider.latitude,
          long: provider.longitude,
          name: provider.name
         });
     })
    }
    // Sending final response against all generated entries to user
    res.send(providerArr) // this is going blank to the browser
  })
  .catch(error => {
    // Sending error response if fails
    res.send(error)
  })

PS: Not tested

Sign up to request clarification or add additional context in comments.

9 Comments

for of loop is only for the objects not for arrays. so this solution is not working for me.
but it's working now after chaning for of to for loop.
@MuhammadAdil The for...of statement creates a loop iterating over iterable objects, including: built-in String, Array, Array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables. It invokes a custom iteration hook with statements to be executed for the value of each distinct property of the object. Here is the doc: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
You are correct. but I tried the for of loop in my code but the loop was not working for me. Not sure why so I tried for loop then.
My providers result is coming from sequelize model directly. maybe it's not real array-like objects or iterable objects.
|
1

Amadou's answer is correct, but it does its processing sequentially instead of in parallel, waiting for each MapGenerator.getMapImage() to finish before firing another request. With some modification, you can fire all of your requests at the same time and wait for all of them to complete.

  static providerMapImageGenerator(req, res) {
    let providerArr = []
    ProvidersRepository.getProviderInfoForMapImage()
      .then(providers => {
        return Promise.all(providers.map(provider => {
          // Generating image against each entr
          return MapGenerator.getMapImage(  // ** actually return the promise so
            provider.latitude,              // ** Promise.all gets an array of promises
            provider.longitude,
            provider.name,
            provider.providerId
          )
            .then(res => {
              // Saving record after each entry
              ProviderMap.create({
                providerId: provider.providerId,
                url: res.Location
              })
              // Adding new array for response
              providerArr.push({
                id: provider.providerId,
                url: res.Location,
                lat: provider.latitude,
                long: provider.longitude,
                name: provider.name
              })
            })
            .catch(err => console.log(err, "err in generating image"))
        })
        // Sending final response against all generated entries to user
        .then(() => res.send(providerArr)); // this is going blank to the browser
      })
      .catch(error => {
        // Sending error response if fails
        res.send(error)
      })
  }

1 Comment

with above promise.all my response would be the same as I wanted

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.