Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【Next.js +TypeScript】 getStaticPropsの中でPromise allしたい

解決したいこと

タイトルのとおりです。データを取得する処理を短く書き直すリファクタをしています。

リファクタ前(これは期待通りの動きをしています)

export const getStaticProps = async () => {
  const topRes1 = await fetch(`${process.env.API_BASE_URL}?page=1`)
  const topRecruiting1 = await topRes1.json()
  const page1 = topRecruiting1.data

  const topRes2 = await fetch(`${process.env.API_BASE_URL}?page=2`)
  const topRecruiting2 = await topRes2.json()
  const page2 = topRecruiting2.data

  const topRes3 = await fetch(`${process.env.API_BASE_URL}?page=3`)
  const topRecruiting3 = await topRes3.json()
  const page3 = topRecruiting3.data

  const data = [page1, page2, page3]

  return {
    props: {
      data,
    },
    // ISR:page re-generation can occur in 10 minutes.
    revalidate: 60 * 10,
  }
}

こんなかんじになってほしいです↓

export const getStaticProps = async () => {
  const pageNum = [1, 2, 3]
  const promises = pageNum.map((num) =>
    fetch(`${process.env.API_BASE_URL}?page=${num}`)
  )
  // =[topRes1,topRes2,topRes3]

  const data = Promise.all(promises)
    .then((values) => values.map((value) => value.json()))
    // ↑まず各々のレスポンスをJSONにし、
    .then((values) => values.map((value: any) => value.data))
    // jsonの中のdataオブジェクトをとってくる
  return {
    props: {
      data,
    },
    // ISR:page re-generation can occur in 10 minutes.
    revalidate: 60 * 10,
  }
}

発生している問題・エラー

Server Error
Error: Error serializing `.data` returned from `getStaticProps` in "/".
Reason: `object` ("[object Promise]") cannot be serialized as JSON. Please only return JSON serializable data types.

This error happened while generating the page. Any console logs will be displayed in the terminal window.```

Promiseについての理解が浅く...ご助言ください!

0

1Answer

value.json()の戻り値がPromiseなので、以下のところでjsonではなくPromiseオブジェクトにアクセスしてます。

    .then((values) => values.map((value: any) => value.data)) // <- valuesはPromiseの配列
    // jsonの中のdataオブジェクトをとってくる

fetchのところでjson変換までやっちゃえば行けると思います。


  const promises = pageNum.map((num) =>
    fetch(`${process.env.API_BASE_URL}?page=${num}`).then((value) => value.json())
  )
1Like

Comments

  1. @hajimism

    Questioner

    こんな感じでかくことができました!ありがとうございます!

    ```tsx
    // page=3までのデータをすべてfetchし、jsonに
    const promises = pageNum.map((num) =>
    fetch(`${process.env.API_BASE_URL}?page=${num}`).then((value) =>
    value.json()
    )
    )

    let data: any = []

    // jsonの中からdataという名のオブジェクトを抽出
    await Promise.all(promises).then((values) =>
    values.map((value: any) => data.push(value.data))
    )
    ```

Your answer might help someone💌