検索バーのオプションをオートコンプリートするために react-select を使用しています。検索バーには、ヒットしたAPIエンドポイントに応じて、2つのカテゴリのいずれかの結果が表示されます。
現時点では、どちらか一方のデータを処理しますが、両方のエンドポイントからデータを返して反応選択のloadOptions
パラメータに返すのに問題があります。
複数のAPI呼び出しについて この回答 から、Promiseを使用してすべてのデータを一度に返すことにしましたが、エラーUncaught TypeError: promise.then is not a function at Async.loadOptions
が発生します
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}
})
}
あなたの問題は、getAsync
がalwaysを返さないということです。そのため、すべての呼び出しに.then(…)
をチェーンすることができませんでした。入力がない場合は、プレーンオブジェクトを返していました。代わりに、そのオブジェクトで解決されるpromiseを返す必要があります。
if (!input) {
return Promise.resolve({ options: [] });
}
したがって、ifステートメントがエラーの原因であることがわかります。
if (!input) {
return {options: []}
}
しかし、なぜそうなるのかはわかりません。誰かが理由を説明できれば、それは将来の問題について知っておくと良いでしょう。
@Bergiのアドバイスに従って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}
})
}