getStaticPaths - data.map is not a function - javascript

I am using Strapi with Next.js for my blog project
I am trying to make dynamic pages by using [id].js inside pages/posts/[id].js
But, the problem is when I try to map through the API of Strapi inside getStaticPaths() it gives me an error with data.map is not defined
Note:- I am using NextJS V12.0.8 with Strapi V4.0.4
Below is my code
export async function getStaticPaths() {
const postsRes = await axios.get("http://localhost:1337/api/posts?populate=image");
const paths = postsRes.map((post) => {
return { params: {id: post.id.toString()} }
});
// const paths = { params: {id: '1' } }
return {
paths,
fallback: false
}
}
Complete [id].js Page Code Link - https://pastebin.com/SnzLirys
Error Screenshot - https://prnt.sc/26ha6z5

apparently you need to set up a context to use axios inside that function, or you can try to format the axios response to json.stringfy and then use json.parse in it. or just use fetch.
in case you are using next api folder, don't call fetch or axios here, just make the query as if you were in node
export async function getStaticPaths() {
const get = await fetch("url")
const data = await get.json()
data.map(item => console.log(item))
const paths = data.map((post) => {
return { params: {id: post.id.toString()} }
});
// const paths = { params: {id: '1' } }
return {
paths,
fallback: false
}
}

Related

Sveltekit Error: `page` in `load` functions has been replaced by `url` and `params`

I am trying to display my date from GraphCMS in my blog application. I receive this error when I go to my single post link (http://localhost:3000/posts/union-types-and-sortable-relations)
"
page in load functions has been replaced by url and params
Error: page in load functions has been replaced by url and params
"
Here is my code
<script context='module'>
export const load = async ({fetch, page: {params}}) => {
const {slug} = params
const res = await fetch(`/posts/${slug}.json`)
if(res.ok) {
const {post} = await res.json()
return {
props: {post},
}
}
}
</script>
<script>
export let post
</script>
<svelte:head>
<title>Emrah's Blog | Welcome</title>
</svelte:head>
<pre>{JSON.stringify(post, null, 2)}</pre>
Can you please help. Thanks
Try using params instead of page: params, though the latter still works in Sveltekit 278 (which I'm using).
Besides, I'm curious to know what makes you prefer this method to querying GraphCMS for your single post. I do it like this:
import {client} from '$lib/js/graphql-client'
import {projectQuery} from '$lib/js/graphql-queries'
export const load = async ({ params }) => {
const {slug} = params
const variables = {slug}
const {project} = await client.request(projectQuery, variables)
return {
props: {
project
}
}
}
Yes, this has been changed a while ago, now the different parts of what used to be page are passed directly into the load function:
export async function load({ fetch, page }) {
const { params, url } = page
}
export async function load({ fetch, params, url }) {
}
Something else to consider is that now there are page endpoints, if your file is [slug].svelte you can make a file [slug].js and add the following:
export async function get({ params }) {
const { slug } = params;
const post = {}; // add the code to fetch from GraphCMS here
return {
status: 200,
body: {
post
}
}
}
With this you can remove the load function and make your code simpler (especially because you technically already have all this code in your /posts/[slug].json.js file.
<script context='module'>
export async function load({ fetch, params}){
let id = params.users
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
const user = await response.json()
if(response.ok){
return {props:{user}}
}
return {
status: response.status,
error : new Error(" sorry no user found")
}
}
export let user

Error: Error serializing `.data[4].description` returned from `getStaticProps` in "/" [duplicate]

I'm working with Next.js, I tried accessing data but got this error:
Error: Error serializing `.profileData` returned from `getStaticProps` in "/profile/[slug]".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.
My code:
import { getAllBusinessProfiles } from '../../lib/api';
const Profile = ({ allProfiles: { edges } }) => {
return (
<>
<Head>
<title>Profile</title>
</Head>
<Hero />
<section>
{edges.map(({ node }) => (
<div key={node.id}>
<Link href={`/profile/${node.slug}`}>
<a> {node.businessInfo.name} </a>
</Link>
</div>
))}
</section>
</>
);
}
export default Profile;
export async function getStaticProps() {
const allProfiles = await getAllBusinessProfiles();
return {
props: {
allProfiles
}
};
}
getAllBusinessProfiles from api.js:
const API_URL = process.env.WP_API_URL;
async function fetchAPI(query, { variables } = {}) {
const headers = { 'Content-Type': 'application/json' };
const res = await fetch(API_URL, {
method: 'POST',
headers,
body: JSON.stringify({ query, variables })
});
const json = await res.json();
if (json.errors) {
console.log(json.errors);
console.log('error details', query, variables);
throw new Error('Failed to fetch API');
}
return json.data;
}
export async function getAllBusinessProfiles() {
const data = await fetchAPI(
`
query AllProfiles {
businessProfiles(where: {orderby: {field: DATE, order: ASC}}) {
edges {
node {
date
title
slug
link
uri
businessInfo {
name
title
company
image {
mediaItemUrl
altText
}
highlight
phone
city
country
facebook
instagram
email
website
profiles {
profile
profileInfo
}
extendedProfile {
title
info
}
}
}
}
}
}
`
);
return data?.businessProfiles;
};
What could be the error here? I used the getStaticProps method on Next.js but got the error above instead. Please, check. Thanks.
The error:
Server Error
Error: Error serializing .profileData returned from getStaticProps in "/profile/[slug]".
Reason: undefined cannot be serialized as JSON. Please use null or omit this value.
I don't know what could cause this though.
Add JSON.stringify when calling an asynchronous function that returns an object.
Try modifying your getStaticProps function like this.
export async function getStaticProps() {
const profiles = await getAllBusinessProfiles();
const allProfiles = JSON.stringify(profiles)
return {
props: {
allProfiles
}
};
}
The JSON.stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
Source: MDN
I had this issue using Mongoose and Next.js.
To solve it: I switched from convert require to import then wrapped my result in JSON.parse(JSON.stringify(result));.
Good: import mongoose from 'mongoose';
Bad: const mongoose = require('mongoose');
I had the same serialization error when accessing a Vercel system environment variable in getStaticProps.
Using JSON.stringify did not do the trick, but String() worked. My code:
export async function getStaticProps() {
const deploymentURL = String(process.env.NEXT_PUBLIC_VERCEL_URL);
return {
props: {
deploymentURL,
},
};
}
Thanks to this GitHub issue for the inspiration
I had the same issue when I was working with redux with next js and the reason was one of the fields in the default state I set it to undefined. Instead I used null:
const INITIAL_STATE = {
products: [],
loading: false,
error: undefined,
cart: [],
};
error:undefined was causing the error. Because "undefined" cannot be serialized:
export async function getStaticProps() {
const allProfiles = await getAllBusinessProfiles();
return {
props: {
allProfiles
}
};
}
you are returning "allProfiles" which is the result of async getAllBusinessProfiles() which is either returning undefined, error or one of the fields of the returned object is undefined. "error" object is not serializable in javascript
Instead of using undefined, you have to use null as the value for your variables.
Note that the error shows you exactly which variable is using undefined as its value. Just modify its value to be null.
The value 'undefined' denotes that a variable has been declared, but hasn't been assigned any value. So, the value of the variable is 'undefined'. On the other hand, 'null' refers to a non-existent object, which basically means 'empty' or 'nothing'.
Source: [1]
I was having the same issue while trying to find a match in the array of data using the id. The issue I had was the items in the array had ids which were numbers while the value I was getting from params was a string. So all i did was convert the number id to a string to match the comparison.
export async function getStaticProps({ params }) {
const coffeeStore = coffeeStoreData.find(
(store) => store.id.toString() === params.slug[0]
);
return {
props: {
coffeeStore,
},
};
}
install a package called babel-plugin-superjson-next and superjson and added a .babelrc file with these contents:
{
"presets": ["next/babel"],
"plugins": ["superjson-next"]
}
see this topic : https://github.com/vercel/next.js/discussions/11498.
I had a similar problem too where I was fetching data through apollo directly inside of getStaticProps. All I had to do to fix the error was add the spread syntax to the return.
return {
props: {
data: { ...data }
}
}
return { props: { allProfiles: allProfiles || null } }
In getStaticProps() function, after fetching your data it will be in json format initially, but you should change it as follow:
const res = await fetch(`${APP_URL}/api/projects`);
const data = JSON.parse(res);
now it will work.
When you call api you should use try catch. It will resolve error.
Example:
import axios from "axios";
export const getStaticProps = async () => {
try {
const response = await axios.get("http:...");
const data = response.data;
return {
props: {
posts: data
}
}
} catch (error) {
console.log(error);
}
}
Hope help for you !
put res from API in Curly Brackets
const { res } = await axios.post("http://localhost:3000/api", {data})
return { props: { res } }
try this, it worked for me:
export async function getStaticProps() {
const APP_URL = process.env.PUBLIC_NEXT_WEB_APP_URL;
const res = await fetch(`${APP_URL}/api/projects`);
const projects = await res.json();
return {
props: {
projects: projects?.data,
},
};
}

getStaticProps Does not return any data to the pages on Next.JS

I'm trying to fetch a data from my hosted database. The database itself are working (I have checked it from the swagger app) but no data is shown when it is called from API form.
import React from 'react';
export const getStaticPaths = async () => {
const res = await fetch('https://[server]/course');
const data = await res.json();
const paths = data.result.map(course => {
return {
params: { id: course._id.toString() }
}
})
return {
paths,
fallback: false
}
}
export const getStaticProps = async (context) => {
const id = context.params.id;
const res = await fetch('https://[server]/course/' + id);
const data = await res.json();
return {
props: { course: data }
}
}
const Details = ({ course }) => {
return (
<div>
<h1> { course.course_name } </h1>
<h1>a</h1>
</div>
);
}
export default Details;
The code is in the pages folder. I followed a tutorial on youtube from "netninja" and when I tried it on his code it works. I read somewhere that it won't work on components but I already put it on the pages but it still does not return anything.
Is there anything I can do ?
I got the answer. After checking console.log on the data. Looks like the data is on another array which is called result. so i needed to call the data from course.result.course_name. So the Answer is just to check console.log every once in a while. Shout out to juliomalves for pointing that out

How to pass a parameter in getStaticProps in Nextjs

I just want to ask how can I call an API when a user "click the search button" and display the appropriate result in NextJS. Thank you!
This is the API I'm using https://www.themealdb.com/api/json/v1/1/search.php?s=Steak and note the "Steak" word is the food I want to see.
Here is my url in development mode http://localhost:3000/search/steak/.
I want to pass the "steak" in getStaticProps and pass the result of getStaticProps in my component.
export const getStaticProps = async () => {
const res = await axios.get(
'https://www.themealdb.com/api/json/v1/1/search.php?s=Steak'
);
return {
props: {
meals: res.data,
},
};
};
I think you can't do it. GetStaticProps render the page at build time, so you can't render a page based on user request.
I suggest you to read this docs, section 'when I should use GetStaticProps'.
You can use react state, or GetServerSideProps (read the same docs).
You can also static render a bunch of page using GetStaticPath and pass, for example, the 10 most searched foods.
You can do this with getStaticPaths if you are using dynamic routes.
You can use search/[slug].js as a dynamic route in your file based routing.
Then, in [slug].js you would have something like:
export default function Page({ response }) {
return <div>{JSON.stringify(response)})</div>
}
// get all the possible paths for the individual ingredients
export async function getStaticPaths() {
const data = await axios.get(
'www.themealdb.com/api/json/v1/1/list.php?i=list'
);
return {
paths: data.meals.map((ingredient) => ({
params: { slug: ingredient.strIngredient.toString().toLowerCase. },
})),
fallback: false, // can also be true or 'blocking'
}
}
export async function getStaticProps({ params }) {
const { slug } = params
const response = await axios.get(
`https://www.themealdb.com/api/json/v1/1/search.php?s=${slug}`
);
return {
props: {
response
},
}
}

How to get rid of use absolute urls error when trying to async action creators in React?

I keep getting the error that I need to use absolute URL's from fetch when I am trying to mock the test call with fetchMock and nock.
describe('fetchFileNames creator #AT-fetchTodosIfNeeded#', () => {
it('should create RECEIVE_FILE_NAMES_SUCCESS after the fetching is done', () => {
const fileNames = ['testFile1', 'testFile2', 'testFile3'];
const expectedActions = [
{ type: ac.REQUEST_FILE_NAMES },
{ type: ac.RECEIVE_FILE_NAMES_SUCCESS, fileNames }
];
const store = mockStore({
files: {
fileNames
}
});
fetchMock.get('*', { files: fileNames});
return store.dispatch(at.fetchFileNames())
.then(() => {
var createdActions = store.getActions();
delete createdActions[1].receivedAt;
expect(store.getActions()).to.deep.equal(expectedActions);
});
});
});
The code turned out to be okay. I was importing isomorphic-fetch incorrectly into the async action creators file. What I was doing: import fetch from isomorphic-fetch what I should have been doing: import isomorphic-fetch. It's documented in fetch-mock, but I missed it and this was getting frustrating.

Categories

Resources