1

I have a page on my website where i retrieve 1 project from the Firebase Cloud Firestore. This website is being made with Vue.js and Nuxt.js. I am getting this project thru an API that me and my friend made with Express.js. On the page there is a gallery with images, i want to use the package Photoswipe to be able to swipe thru the images, but i need the image dimentions for that. Since i cannot set the dimentions when i am saving my document to firebase i am trying to get the image dimentions when recieving the project inside the API. I am trying to do this by using the package probe-image-size inside a foreach loop that loops thru all the gallery images.

My problem is that i cannot seem to set the dimention values to the data object from the inside of the .then() promise.

I have tried returning values from inside the promise, but that does not seem to work for me.

this is the API endpoint for getting a specific project:

router.get('/:id', api(async req => {
  let item, doc = null

  try {
    doc = await collection.doc(req.params.id).get()
  } catch (err) {
    console.error(`Error getting project ${req.params.id}:`, error);
  }

  if (doc && doc.exists) {

    const data = doc.data()


    const probe_promises = data.images.map(image => probe(image.url).then(res => {
      image.width = res.width;
      image.height = res.height;
    }))

    await Promise.all(probe_promises)

    console.log(data.images);

    item = data
  }

  return item
}));

This is the part that is throwing the Request failed with status code 500 error, without this part the code works fine:

const probe_promises = data.images.map(image => probe(image.url).then(res => {
      image.width = res.width;
      image.height = res.height;
    }))

    await Promise.all(probe_promises)

    console.log(data.images);

this is the exact error that it is throwing:

 Request failed with status code 500
[0] 
[0]   at createError (node_modules/axios/lib/core/createError.js:16:15)
[0]   at settle (node_modules/axios/lib/core/settle.js:17:12)
[0]   at IncomingMessage.handleStreamEnd (node_modules/axios/lib/adapters/http.js:237:11)
[0]   at IncomingMessage.emit (events.js:208:15)
[0]   at IncomingMessage.EventEmitter.emit (domain.js:471:20)
[0]   at endReadableNT (_stream_readable.js:1161:12)
[0]   at processTicksAndRejections (internal/process/task_queues.js:77:11)

The weird thing is that when i remove the probe code and reload the page, then add the code again and reload the page again it works.

stefan de boer
  • 389
  • 1
  • 8
  • 20

2 Answers2

1

Actually, it's not how you should use Promises: item callback called asynchronously. It means you return item before it will be assigned in this callback. To get promise value in the caller function you just need to return item from promise and return this promise from router.get() function.

Andres
  • 967
  • 6
  • 7
1

There are some Promise usage errors. Don't mix async/await with then/catch, or at least do it only when you are forced to.

The array.foreach() doesn't wait for promises but start them without do anything else. A solution is to map all the promises and then wait for them.

router.get('/:id', api(async req => {
  let item, doc = null

  try {
    doc = await collection.doc(req.params.id).get()
  } catch (err) {
    console.error(`Error getting project ${req.params.id}:`, error);
  }

  if (doc && doc.exists) {

      const data = doc.data()

      probe_promises = data.images.map(image => probe(image.url).then(res => {
        image.width = res.width;
        image.height = res.height;
      }))

      await Promise.all(probe_promises)

      console.log(data.images);
      item = data
  }

  return item
}));
Andrea Franchini
  • 548
  • 4
  • 14
  • Unfortunately your code throws an error : `Request failed with status code 500` – stefan de boer Oct 07 '19 at 12:06
  • Unfortunately i don't know the rest of your code, so it can be an image without url, the probe function, res.width or heigth. If you post more detail we can find out what is the problem. – Andrea Franchini Oct 07 '19 at 13:29
  • I edited my post with some useful info. I also posted the part where i think the code throws the error. – stefan de boer Oct 07 '19 at 13:42
  • 1
    Turns out my Firebase Cloud Storage rules were preventing me from viewing certain files if i was not authenticated. Now that i changed the rules the code you wrote works perfect. Thank you! – stefan de boer Oct 08 '19 at 11:29