How do I get the next-auth session with getStaticPaths and getStaticProps in dynamic routing?
Asked Answered
F

1

6

I'm trying to implement dynamic routing in a NextJS app. I need the token from next-auth to get the data from getReport and getReports (in /reports.js) via an axios request to an API, but I don't know how to get it. It works when I try it with the token hard coded in [itemId].js, so the routing is working fine (I think).

Since getStaticPaths and getStaticProps runs on the server, I tried using getSession(), but I'm not sure if it doesn't work or I didn't used it correctly, but I could never get the session. Using getSession() would be the preferable option for me.

I also tried saving it in localStorage, but getStaticProps can't access localStorage.

I'm thinking of using Redux, but I'd really like to avoid it.

Here is my code:

/pages/user/reports/[reportId]/[itemId].js

import { useSession } from "next-auth/react";
import { useLayoutEffect } from "react";
import Loading from "../../../../components/Loading";
import Layout from "../../../../components/user/layout/Layout";
import { getAllReportsIds, getReportItem } from "../../../../components/user/reports";

const token = 'here is currently the token'

export default function Report({ reportItem }) {
  return (
    <Layout>
      {/* Start Page Header */}
      <div className="page-header">
      <h1 className="title">{ reportItem.name }</h1>
        <ol className="breadcrumb">
          <li className="active">{ reportItem.description }</li>
        </ol>
      </div>
      {/* End Page Header */}

      {/* START CONTAINER */}
      <div className="container-padding">

        {/* Start Row */}
        <div className="row">

          {/* Start Panel */}
          <div className="col-md-12">
            <div className="panel panel-default">
              
              <div className="panel-body">
                <div className="embed-responsive embed-responsive-16by9">
                  <iframe title="Reporte" className="embed-responsive-item" src={reportItem.code} allowFullScreen></iframe>
                </div>
              </div>
              
            </div>
          </div>
          {/* End Panel */}
        
        </div> 
        {/* End Row */}

      </div>
      {/* END CONTAINER */}
    </Layout>
  )
}

export async function getStaticPaths() {
  const paths = await getAllReportsIds(token)
  return {
    paths,
    fallback: false
  }
}

export async function getStaticProps(context) {
  console.log('context en static props: ', context)
  try {
    const reportItem = await getReportItem(token, context.params.reportId, context.params.itemId)
    return {
      props : {
        reportItem
      }
    }
  } catch(error) {
    console.log('error: ', error)
    return {
      props : {
        error: true
      }
    }
  }  
}

/components/user/reports.js

import { getReport, getReports } from "../../pages/api/axios/reports";

export async function getAllReportsIds(token) {
  try {
    const { data } = await getReports(token)
    let reportIds = []
    reportIds = data.flatMap(report => {
      return (
        report.report_items.map(item => {
          return {
            params: {
              reportId: JSON.stringify(report.id),
              itemId: JSON.stringify(item.id)
            }
          }
        })
      )
    })
    return reportIds
  } catch(error) {
    console.log('error: ', error)
  }
}

export async function getReportItem(token, reportId, itemId) {
  try {
    const { data } = await getReport(token, reportId)
    let reportItem = {}

    data.report_items.map(item => {
      if (JSON.stringify(item.id) === itemId) {
        reportItem = item
      }
    })
    return reportItem
  } catch(error) {
    console.log('error: ', error)
  }
}

If anyone can help, it would be really appreciated.

Faena answered 6/3, 2022 at 1:15 Comment(1)
For data that depends on the user, you should be using getServerSide props instead, or fetch the data client side. The reason is that staticProps gets called at build time, so you would not have any user logged in.Area
F
6

For some reason I thought I needed to use getStaticPaths, but I was getting the path from context.params, so I solved it by just removing that function and using getServerSideProps (like Mentlegen mentioned).

export async function getServerSideProps(context) {
  const session = await getSession(context)
  try {
    const reportItem = await getReportItem(session.token, context.params.reportId, context.params.itemId)
    return {
      props : {
        reportItem
      }
    }
  } catch(error) {
    console.log('error: ', error)
    return {
      props : {
        error: true
      }
    }
  }  
}
Faena answered 9/3, 2022 at 3:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.