Utilize Next JS pages api to generate dynamic routes based on unique ids

In the content of my website, there is a collection of objects named stories that are displayed as an array. Additionally, I have a section where each individual story is showcased in detail.

I intend to enable users to click on any story link within the list and be directed to the detailed page for that specific story. Utilizing the _id as a dynamic component of the URL is key, as illustrated below in the GraphQL code snippet.

The Graphql Query

export const listAllStories = () => {
  const query = gql`
    query StoryEntries($size: Int) {
      storyEntries(_size: $size) {
        data {
          _id
          _ts
          name
          premises{
            data{
              _id
              content
            }
          }
          createdAt
        }
      }
    }
  `

  return graphQLClient
      .request(query, { size: 999 })
      .then(({ storyEntries: { data } }) => data)
}

Within My Pages API

export default async function handler(req, res) {
  const handlers = {
    GET: async () => {
      const storyEntries = await listAllStories()
      res.json(storyEntries)
    },
  }

  if (!handlers[req.method]) {
    return res.status(405).end()
  }

  await handlers[req.method]()
}

In The Overview Page For Each Story

const ENTRIES_PATH = '/api/entries/allStories'

const useEntriesFlow = ({ initialEntries }) => {
    const { data: entries } = useSWR(ENTRIES_PATH, {
        initialData: initialEntries,
    })

    const EntryItem = ({ entry }) => (
         <>
            {entries?.map((entry) => (
                  {entry.name}
       <Link href="/story/[storyId]" as={`/story/${entry._id}`}>
                                <a>Go</a>
                            </Link>
             ))}
         </>
    )

export const getStaticProps = async () => ({
    props: {
        initialEntries: await listAllStories(),
    },
    revalidate: 1,
})

This implementation functions correctly and meets the requirements.

**On The Detailed Page For Each Individual Story [storyId].js **

export default function Story({story}) {

    const router = useRouter()
    const storyId = router.query.storyId
    return(
        <>
            <h5>hello {story._id}</h5>
        </>
    )
}

export const getStaticPaths = async () => {
    const res = await fetch(`${server}/api/entries/allStories/`);
    const { data } = await res.json();
    const paths = data.map(story => {
        return {
            params: { id: story._id.toString() }
        }
          // Extracting the _id from each story 
    })
    return {
        paths,
        fallback: false
    }
}

    export const getStaticProps = async (context) => {
    const { storyId } = context.query;    
    const server = "http://localhost:3000";

    const res = await fetch(`${server}/api/entries/allStories/${storyId}`);
    console.log(res)
    const { data } = await res.json();
    return {
        props: { story: data }
    }
}

Error Message

TypeError: Cannot read properties of undefined (reading 'map')

Question

The main objective is to seamlessly navigate between the story list and individual story details using the unique _id associated with each story. Despite numerous attempts, I seem to be encountering issues or errors along the way.

Your assistance and guidance on this matter would be sincerely appreciated.

Edit After Receiving An Error: There appears to be difficulty in mapping the results obtained in the getStaticPaths method.

https://i.stack.imgur.com/e1xDs.png

Answer №1

const fetchData = async (context) => {
    const { postId } = context.query;
    const serverUrl = "YOUR SERVER URL";

    const response = await fetch(`${serverUrl}/api/posts/getPost/${postId}`);
      
    const { postData } = await response.json();
    return {
        fetchedData: { post: postData }
    }
}

Answer №2

remove comment

let router = useRouter()
let id = router.query.storyId

Answer №3

// check out these useful resources
// https://nextjs.org/docs/basic-features/data-fetching#the-paths-key-required
// https://stackoverflow.com/questions/65783199/error-getstaticpaths-is-required-for-dynamic-ssg-pages-and-is-missing-for-xxx

export const getStaticPaths = async () => {
    const server = "http://localhost:3000";

    const data = await fetch(`${server}/api/entries/allStories/`).then(res => res.json() )

    const paths = data.map(({_id}) => ({
        params: { storyId: _id },
    }))

    return {
        paths,
        fallback: false
    }
}

export const getStaticProps = async (context) => {

    const storyId = context.params.storyId;    // Dynamic page [storyId].js
    const server = "http://localhost:3000";

    // const res = await fetch(`${server}/api/entries/allStories/${storyId}`);
    // trying to get the params._id from each story 
    // single api call (here)
    const res = await fetch(`${server}/api/entries/allStories/`);
    // removing const { data } because the data will be returned when calling res.json()
    const data = await res.json();
    // instead of calling the single API (fix not recommended to access [0] directly )
    return {
        props: { story: data.filter(story => story._id === storyId)[0] }
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Extracting HTML elements between tags in Node.js is a common task faced

Imagine a scenario where I have a website with the following structured HTML source code: <html> <head> .... <table id="xxx"> <tr> .. </table> I have managed to remove all the HTML tags using a library. Can you suggest w ...

What is the process of duplicating form fields using PHP?

Currently, I am facing an issue with my clients' landing page setup. The landing page is designed to input any new signups into Salesforce. However, the information flow is primarily directed towards my system, which requires specific form field ids. ...

Troubleshooting why content set to a <div> element with JavaScript / jQuery is not persisting after a

This is the current code snippet I am working with: <asp:Button ID="btnSave" runat="server" OnClick="Save" CssClass="StylizedButton" resourcekey="btnSave" /> <div id="lbltot"></div> Below is the JavaScript portion of the code: $(do ...

Having trouble setting the select value with JavaScript in the Selenium web driver

I am working on a web page that includes a cascaded dropdown feature. The data in the second dropdown appears to be generated via ajax based on the selection made in the first dropdown. Here is the code for the first select option: <select class="form- ...

Troubleshooting issues with ember-data's belongsTo relationship

I am facing an issue with the model I have: Whenever I make a call to this.store.find('history'); A request is sent to http:://www.example.com/api/histories/ and I receive the following JSON response: { "tracks":[ { "id":83, ...

What could be causing my dropdown menu to not appear when clicked?

I am trying to implement the functionality shown in the image. When the Settings button is clicked, a window should open allowing the user to navigate to their desired option. However, I am facing an issue where nothing happens when the button is clicked. ...

Capturing information within a jQuery function by accessing data from another function

Can data be collected from another function while the function is running? // Custom Function function getData(){ var name = 'tom'; return name } // Main Target Area $('.myDiv').click(function(){ // I need to retrieve dat ...

Utilize jQuery function within an HTML form

I am trying to integrate my jQuery function with an HTML tag for my login form that connects to an Azure database. I want a modal pop-up to appear when the client presses the Login button, displaying a specific message based on whether the user is in the d ...

Encountering a "NextJS Google Drive API error due to Insufficient Permission when using Service

I am currently developing a basic NextJS application with the goal of displaying files from a specific Google Drive folder. The Google Drive folder belongs to my personal account and is shared with a Service Account that I created in Google Cloud Platform ...

Problems encountered when trying to deploy on Firebase

I've been working on deploying my web app to Firebase, and I successfully ran the deploy script. However, when I try to access the URL, instead of seeing my app, I'm greeted with the Open Hosting Documentation page. Here is what my firebase.json ...

When a new ajax function is added, the original Ajax code stops functioning

I've been working on getting the code below to function properly. It seems that when I test the code, two validation functions are working correctly. However, when I include the validateUsername() function along with the if statement in the code, ever ...

Exploring ways to access elements within shadow-root (open) in Angular using SVG.js

I'm currently tackling a project involving Angular Elements. Within this specialized component, my goal is to incorporate SVG.js 3+. However, due to the necessity of utilizing ViewEncapsulation.ShadowDom in my component, I am encountering challenges w ...

Error: Property 'onclick' cannot be set on a null object

JavaScript isn't my strong suit, so I'm struggling to solve this issue. The console is showing me the following error message: Uncaught TypeError: Cannot set property 'onclick' of null <script> var modal = document.getE ...

What is the significance of the exclamation point before and after in JavaScript?

Currently collaborating on a project and attempting to decipher the significance of the exclamation marks both before and after. import ICHING from '!json!constants/iching_deoxy.json'; ...

What is the best way to execute multiple controller functions for a single route?

I have a specific route set up for users to submit loan applications. What I want to achieve is to call different controller functions based on the amount of the loan that the user is applying for. app.use('/submitLoanRequest50kMore', mw1, mw2, ...

The use of dangerouslySetInnerHTML causes the page layout to stretch, expand, or grow in size

I am currently working on my NextJs app, where I'm utilizing CosmicJs as a headless CMS to showcase content on the webpage. Within the layout of my page, I have structured it with 3 columns, and the content pulled from the CMS is meant to be displaye ...

What is the best way to modify the size of a canvas element while maintaining effectiveness?

I've encountered an issue while using Canvas to create a pie chart with chart.js. Despite adjusting the dimensions of the canvas element, it continues to take up the entire page. <canvas id="myChart" height ="200" width="200"></can ...

What steps are involved in integrating QuickBlox on your website?

I am completely new to web development and have a question about integrating QuickBlox into my website using JavaScript. I have included the necessary JavaScript files in my website and set up the QuickBlox admin application, but I'm not sure how to p ...

Animating CSS Pixel Fragments

After applying a simple CSS animation that moves size and box shadows from one side of the screen to the other, I am noticing residual pixel fragments left behind. To see this issue in action on Chrome 66, check out the Code Pen: Is there a way to remove ...

Combining a 3D array into a 2D array with the addition of HTML tags around each value using JavaScript

3D array // Array var x = { "letter": [ "a", "b", "c", "d", "e", "f", "g", "h", "i" ], "line": [ { "data": [ 306, 830, 377, 651, 547, 369, 300, 148, 494 ] }, { "data": [ 88, 339, 298, 87, 96, 108, 93, 182, 64 ] }, { "data": [ 3157, 2943, ...