Promise.then is not a function - handling multiple API calls in React

I am using react-select to auto-populate options in the search bar. The search bar displays results in one of two categories, depending on the API endpoint.

At the moment it is working with data from one point or the other, but I am having trouble returning data from both endpoints to be responsive to selection loadOptions

.

From this answer about multiple API calls, I decided to use promises to return all data at the same time, but I get the errorUncaught TypeError: promise.then is not a function at Async.loadOptions

Here's my code for loadOptions

:

const getAsync = (tripId, destinationIndex, input) => {
  if (!input) {
    return { options: [] }
  }

  function getMusement(input) {
    return new Promise(function(resolve, reject) {
      TVApi.musement.autocomplete(input)
        .then((m) => {
          const musementOptions = m.map(musementToOption).slice(0, 4)
          return resolve(musementOptions)
        })
    })
  }

  function getFourSquare(tripId, destinationIndex, input) {
    return new Promise(function(resolve, reject) {
      TVApi.spot.autocomplete(tripId, destinationIndex, input)
        .then((fs) => {
          const fsOptions = fs.map(spotToOption).slice(0, 4)
          return resolve(fsOptions)
        })
    })
  }

  return Promise.all([getMusement(input), getFourSquare(tripId, destinationIndex, input)])
    .then((allData) => {
      const merged = [].concat.apply([], allData)
      console.log(JSON.stringify(merged)) // logs out with correct data
      return {options: merged}
    })
}

      

+3


source to share


2 answers


Your problem is that getAsync

promise does not always return, so you cannot bind .then(…)

to every call. When there is no input, you return a simple object - instead, you need to return the promise resolved with that object:



if (!input) {
   return Promise.resolve({ options: [] });
}

      

+3


source


So it turns out that the if statement was throwing an error:

if (!input) {
  return {options: []}
}

      

but I have no idea why that would be. If someone can explain why, it would be helpful to know about future issues.



Here's the solution I got after @Bergi avoiding Promise Constructor antipattern

const loadOptions = (tripId, destinationIndex, input) => {

  function getMusement(input) {
    return TVApi.musement.autocomplete(input)
      .then((m) => {
        const musementOptions = m.map(musementToOption).slice(0, 3)
        return musementOptions
      })
  }

  function getFourSquare(tripId, destinationIndex, input) {
    return TVApi.spot.autocomplete(tripId, destinationIndex, input)
      .then((fs) => {
        const fsOptions = fs.map(fsToOption).slice(0, 2)
        return fsOptions
      })
  }

  return Promise.all([getMusement(input), getFourSquare(tripId, destinationIndex, input)])
    .then((allData) => {
      const merged = [].concat.apply([], allData)
      return {options: merged}
    })
}

      

0


source







All Articles