-4

I do not understand how to chain promises:

getUser is a promise function and also search is a promise function. getUser will return a language value.

With this data is not an array value, which should be returned by the search function

getUser(userId)
  .then(({ language }) => {
    const data = search('content', language)
    res.send(200, {
      content: data,
      user: { language }
    })
  })
  .catch((error) => next(error))
user3142695
  • 15,844
  • 47
  • 176
  • 332

2 Answers2

2

To avoid nesting, you can use Promise.all: this will allow you to pass the language value through the chain as well:

getUser(userId)
    .then(({ language }) => 
        Promise.all([language, search('content', language)])
    ).then(([language, data]) => 
        res.send(200, {
            content: data,
            user: { language }
        })
    ).catch((error) => next(error))
trincot
  • 317,000
  • 35
  • 244
  • 286
  • 1
    Could the downvoter please explain what the problem is with this answer? – trincot Aug 22 '17 at 21:50
  • Not the downvoter, but I am curious about why you're using `promise.all` here. Is language a promise? It looks like the return value from getUser. Why can't you just return `search()`'s promise? – Mark Aug 22 '17 at 21:56
  • 1
    When you return only the `search()` promise, then you will not have access to `language` when `res.send` is called (in the flat-chain model). NB: `Promise.all` can deal with non-promise values in the array. In that case it will treat those values as immediately resolved promises. – trincot Aug 22 '17 at 21:58
  • Of course. Thanks. – Mark Aug 22 '17 at 21:59
  • Thanks. I don't see, why this answer was downvoted... Also do not understand why this question is downvoted that much... – user3142695 Aug 22 '17 at 22:01
0

If search returns a promise, then you need to use .then() to get access to the data in that promise. And you should return promises in order to enable chaining at higher levels:

getUser(userId)
  .then(({ language }) => {
    return search('content', language)
      .then((data) => {
        res.send(200, {
        content: data,
        user: { language }
      });
  })
  .catch((error) => next(error))

Note that normally you could avoid nesting by returning the promise returned by search(), and chaining another .then() call afterward, but because you're trying to capture the language parameter from the original method call, you need the value to be in scope. Trincot's answer shows how you can capture the value of language for better chaining.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315