TypeError: Cannot read properties of undefined (reading 'map') in NextJS - getStaticPaths - javascript

I have a problem with dynamic routing in next 13, I have dynamic page [id].js and trying to fetch the data
const res = await fetch(`myAPI`);
const resData = await res.json();
const paths = resData.data.map((r) => ({
params: { id: r.id}
}));
return {
paths,
fallback: false
}
It does not work and gives me error with .map function, if I hard code the path it works without any issue and give me correct output data
Hard coded example:
paths: [
{params: { id: '67'}}
],
I know that my map function should be correct as I tested in inside the component
axios
.get(`myAPI`)
.then((response) => {
console.log(response.data.map((res) => {return(res.id)}))
})
console output in component return data without complaining, why I cannot achieve it in getStaticPath?

resData is already your array of objects, so you can "skip" data:
const res = await fetch(`myAPI`);
const resData = await res.json();
const paths = resData.map((r) => ({
params: { id: r.id}
}));
The reason why when using Axios you have to use data, is because Axios already gets the response data as JSON for you (as data). You were confusing Axios' response for resData.

Related

getServerSideProps not fetching data despite of running it inside the page

hello i am trying to fetch data inside by next app using getServerSideProps which is just not fetching the data , the data returns either an empty object or undefined inside the console i don't know what is wrong with the app , i have tried other next js data-fetching methods too and results are same
export const getServerSideProps = async () => {
// Fetch data from external API
const res = await fetch(`https://rickandmortyapi.com/api/character`)
const data = await res.json()
console.log(data)
// Pass data to the page via props
return { props: { data } }
}
I threw that code into my current project and it works.
interface Props {
data: {
info: any;
results: any[];
}
}
const Page: NextPage<Props> = ({ data }) => {
console.log(data); // { info: {...}, results: Array(20)}
// ...
}
export const getServerSideProps = async () => {
const res = await fetch('https://rickandmortyapi.com/api/character');
const data = await res.json();
return { props: { data } };
};

getStaticPaths - data.map is not a function

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
}
}

REACT HOOKS - Passing JSON data (From API through Axios) into const

In the backend I am processing the data and then sending it to React through JSON. Here is the code.
res.setHeader('Content-Type', 'application/json');
var obj = {field: current, fieldCnt: cnt }
var obj2 = JSON.stringify(obj)
res.write(obj2);
var obj3 = {length: currentcnt, field2: current, fieldCnt2: cnt }
var obj4 = JSON.stringify(obj3)
res.end(obj4);
The backend I showed here is not the same as it is. I just showed it as an example. I had to use res.write and res.end because I had to collect data for different if conditions.
Below here is the code in react where I am getting this data through Axios.
var data2 = axios.get('http://localhost:5000/get').then(res => {
console.log(res.data) //Check the Attached Chrome Developers console image.
return res.data
});
const data3 = data2.length //This isn't working (length can be seen the console image last line "length" : 18)
Chrome Developers console image
Please tell me how to solve this with React Hooks. I think it has to be done with mapping but i don't how.
As #Tobias Geiselmann said axios.get() returns a promise, and you're assigning the length of the promise.
If you return a value from .then(), the next then() is called with that value.
After looking at your screenshot. It looks like you're trying to access the length property from the data return by your API. I would recommend structuring your API response like so
{
count: 18,
results: [
{ key: 'val' },
{ key: 'val' },
{ key: 'val' },
]
}
By doing so you'll be to access the length with:
res.data.count // will have the count
res.data.results // will have all the results
Try this
axios.get('http://localhost:5000/get').then((res) => {
console.log(res.data.length); // will print the length
});
another example:
const data2 = axios.get('http://localhost:5000/get')
.then((data) => {
return data;
});
data2.then(data => {
console.log(data.length) // will print the length
})
example with async/await
const myFunc = async () => {
const { data } = await axios.get('http://localhost:5000/get');
console.log(data.length); // will print the length
};
To solve this with hooks you can fetch data when the component loads with useEffect hook and store it inside useState hook.
const [data, setData] = useState([])
useEffect(() => {
axios.get('http://localhost:5000/get').then(res => setData(res.data))
}, [])
const data3 = data.length

Undefined is not an object while trying to query nested objects. Using axios and React

The JSON response is as shown in the image 1.
I was able to assign the entire response using axios (which already does the JSON.parse) to the state (named profile).
while profile.bio and profile.image are working;
profile.user.username, etc are not working and throwing an error - Undefined is not an object
const [profile, setProfile] = useState({});
const phone_no = phone.phone;
const fetchProfile = useEffect(() => {
var res = {};
axios
.get('<API URL>' + phone_no)
.then((response) => (res = response.data))
.then(() => {
setProfile(res);
})
.then(() => console.log(profile))
.catch((e) => console.log(e)); });
const user_stream = {
name: first.first_name,
image: profile.image,
id: profile.user.id,
};
Update - Solution: Using async-await with axios, it's fixed.
profile or profile.user may still be undefined when trying to access it, so profile.bio is just undefined so it doesn't cause an error, but profile.user.username tries to access a property of an undefined object.
Try adding profile?.user?.username
Or profile && profile.user && profile.user.username
This will ensure that it only tries to render the username if profile is already defined

Fetch data request to nested JSON object error - React/Next.JS

I'm having problems fetching data from my API and I get this error. I have attached the JSON format below as I believe it is an issue with my structure. When I use a different res URL with objects nested inside an array, it works. But for my data, it is not. Can anyone help me please?
"Index.getInitialProps()" should resolve to an object. But found undefined instead"
import Layout from '../comps/Layout';
import Link from 'next/link';
import fetch from 'isomorphic-unfetch';
const Index = props => (
<Layout>
//List of movies here
</Layout>
);
Index.getInitialProps = async function() {
const res = await fetch('https://www.what-song.com/api/recent-movies')
const data = await res.json()
console.log(`Data: ${data}`)
}
export default Index;
The getInitialProps method basically supposed to set your component initial props. But, in your case you are returning nothing.
So, change your code to
Index.getInitialProps = async function() {
const res = await fetch('https://www.what-song.com/api/recent-movies')
const data = await res.json()
console.log(`Data: ${data}`)
return { data }; // <-- set whatever key you want.
}
For your reference

Categories

Resources