-1

I am not sure how to express my question correctly. Basically resolving an async promise with a .map() function works for simple get functions while it doesn't work for get functions with parameter.

Basically, in this case, router.get('/' ... the following works:

import axios from 'axios'

const url = 'http://localhost:3000/api/library/'

class libraryService {
  // Get stories
  static getStories () {
    return new Promise(async (resolve, reject) => {
      try {
        const res = await axios.get(url)
        const data = res.data
        resolve(
          data.map(story => ({
            ...story
          }))
        )
      } catch (err) {
        reject(err)
      }
    })
  }

export default libraryService

While in this case, router.get('/:story_name' ..., this variation doesn't work:

class readService {
  // Get story to read
  static getStoryToRead (storyName) {
    return new Promise(async (resolve, reject) => {
      try {
        const res = await axios.get(url + storyName)
        const data = res.data
        resolve(
          data.map(selectedStory => ({
            ...selectedStory
          }))
...

In here I get an error: 'data.map is not a function'. Changing to data.products.map() will return an error 'Cannot read property 'map' of undefined'.

However resolving data without .map() function will work on all cases:

try {
        const res = await axios.get(...)
        const data = res.data
        resolve(
          data
        )
...

Why this is happening and is it correct to just use resolve(data)?

Marcello
  • 173
  • 1
  • 15
  • 1
    When you ask for a single story why *expect* an array? – jonrsharpe Sep 08 '19 at 16:33
  • 2
    Passing an `async` executor function into `new Promise` so you can use `await` within the executor function [is an antipattern](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it). Use the promise you already have. For instance, that `static getStores` in the first code block can be [**dramatically** simpler](https://pastebin.com/Jq0WZuhN). (Separately: Why clone the stories?) – T.J. Crowder Sep 08 '19 at 16:33

1 Answers1

1

You seem to be asking for a single story in the case that doesn't work. So instead of an array of stories, presuambly you're getting just the one story that you asked for. There's no reason to try to use map.

Minimal changes (but keep reading):

// Minimal changes, but keep reading...
static getStoryToRead (storyName) {
  return new Promise(async (resolve, reject) => {
    try {
      const res = await axios.get(url + storyName);
      resolve(res.data);
    } catch (err) {
      reject(err);
    }
  });
}

But, both of those functions demonstrate the Promise creation antipattern. You already have a promise, work with it. In this case, you'd probably do that by making the functions async:

static async getStories () {
  const {data} = await axios.get(url);
  return data.map(story => ({ // Why copy the story objects?
    ...story
  }));
}

static async getStoryToRead (storyName) {
  const {data} = await axios.get(url + storyName));
  return data;
}

Or with non-async functions:

static getStories () {
  return axios.get(url)
    .then(({data}) => data.map(story => ({...story}))); // Why copy the story objects?
}

static getStoryToRead (storyName) {
  return axios.get(url + storyName))
    .then(({data}) => data);
}
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Thank you, this is a very comprehensive answer! – Marcello Sep 09 '19 at 12:02
  • Trying the non-async function suggested: 1) the getStories() works if I do .then(({data}) => data). Why? 2) Also if I use the non-static functions, my editor warns me that the function might be transformed into an async. So why not using an async function in the first place? – Marcello Sep 09 '19 at 15:18
  • 1
    @Marcello - Hi! 1) Because it's using destructuring. `.then(({data}) => data)` is equivalent to `.then(res => res.data)` if that helps. 2) (I assume you meant "...if I use the non-**async** functions...") I would suggest that you *do* use the `async` version. I included the non-`async` version just in case you didn't want to. :-) – T.J. Crowder Sep 09 '19 at 15:27