In my code I try to get to the 2 thumbnail urls in the JSON below. I'm only able to get in the first Array the
<>{post.attributes.description}</>
but I'm not able to get in the second array the
<>{img.attributes.formats.thumbnail.url}</>
I am getting the error:
TypeError: Cannot read properties of null (reading 'map')
11 | <div key={post.id}>
12 | <>{post.attributes.description}</>
> 13 | {post.attributes.image["data"].map((img) => (
| ^
14 | <div key={img.id}>
15 | <>{img.attributes.name}</>
16 | </div>
Code
import React from "react";
export default function Home({ posts }) {
return (
<div>
{posts["data"].map((post) => (
<div key={post.id}>
<>{post.attributes.description}</>
{post.attributes.image["data"].map((img) => (
<div key={img.id}>
<>{img.attributes.formats.thumbnail.url}</>
</div>
))}
</div>
))}
</div>
);
}
export async function getStaticProps() {
const res = await fetch("http://localhost:1337/api/games?populate=*");
const posts = await res.json();
return {
props: { posts },
};
}
JSON:
{
"data": [
{
"id": 1,
"attributes": {
"title": "gw2",
"description": "test",
"createdAt": "2022-02-18T21:11:17.405Z",
"updatedAt": "2022-02-20T16:39:07.188Z",
"publishedAt": "2022-02-18T21:11:18.345Z",
"image": {
"data": [
{
"id": 1,
"attributes": {
"name": "ddda8Screenshot-02-EfLA-1920x1080.jpg",
"alternativeText": "ddda8Screenshot-02-EfLA-1920x1080.jpg",
"caption": "ddda8Screenshot-02-EfLA-1920x1080.jpg",
"width": 1920,
"height": 1080,
"formats": {
"thumbnail": {
"name": "thumbnail_ddda8Screenshot-02-EfLA-1920x1080.jpg",
"hash": "thumbnail_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
"ext": ".jpg",
"mime": "image/jpeg",
"width": 245,
"height": 138,
"size": 7.88,
"path": null,
"url": "/uploads/thumbnail_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg"
},
"large": {
"name": "large_ddda8Screenshot-02-EfLA-1920x1080.jpg",
"hash": "large_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
"ext": ".jpg",
"mime": "image/jpeg",
"width": 1000,
"height": 563,
"size": 80.97,
"path": null,
"url": "/uploads/large_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg"
},
"medium": {
"name": "medium_ddda8Screenshot-02-EfLA-1920x1080.jpg",
"hash": "medium_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
"ext": ".jpg",
"mime": "image/jpeg",
"width": 750,
"height": 422,
"size": 49.54,
"path": null,
"url": "/uploads/medium_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg"
},
"small": {
"name": "small_ddda8Screenshot-02-EfLA-1920x1080.jpg",
"hash": "small_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
"ext": ".jpg",
"mime": "image/jpeg",
"width": 500,
"height": 281,
"size": 25.21,
"path": null,
"url": "/uploads/small_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg"
}
},
"hash": "ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
"ext": ".jpg",
"mime": "image/jpeg",
"size": 258.19,
"url": "/uploads/ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"createdAt": "2022-02-20T16:37:41.604Z",
"updatedAt": "2022-02-20T16:37:41.604Z"
}
},
{
"id": 2,
"attributes": {
"name": "76ade04-Flame-Frost-Dyes-1920x1080.jpg",
"alternativeText": "76ade04-Flame-Frost-Dyes-1920x1080.jpg",
"caption": "76ade04-Flame-Frost-Dyes-1920x1080.jpg",
"width": 1920,
"height": 1080,
"formats": {
"thumbnail": {
"name": "thumbnail_76ade04-Flame-Frost-Dyes-1920x1080.jpg",
"hash": "thumbnail_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
"ext": ".jpg",
"mime": "image/jpeg",
"width": 245,
"height": 138,
"size": 10.28,
"path": null,
"url": "/uploads/thumbnail_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg"
},
"large": {
"name": "large_76ade04-Flame-Frost-Dyes-1920x1080.jpg",
"hash": "large_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
"ext": ".jpg",
"mime": "image/jpeg",
"width": 1000,
"height": 563,
"size": 113.82,
"path": null,
"url": "/uploads/large_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg"
},
"medium": {
"name": "medium_76ade04-Flame-Frost-Dyes-1920x1080.jpg",
"hash": "medium_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
"ext": ".jpg",
"mime": "image/jpeg",
"width": 750,
"height": 422,
"size": 70.06,
"path": null,
"url": "/uploads/medium_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg"
},
"small": {
"name": "small_76ade04-Flame-Frost-Dyes-1920x1080.jpg",
"hash": "small_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
"ext": ".jpg",
"mime": "image/jpeg",
"width": 500,
"height": 281,
"size": 34.66,
"path": null,
"url": "/uploads/small_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg"
}
},
"hash": "76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
"ext": ".jpg",
"mime": "image/jpeg",
"size": 348.37,
"url": "/uploads/76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"createdAt": "2022-02-20T16:37:41.616Z",
"updatedAt": "2022-02-20T16:37:41.616Z"
}
}
]
}
}
},
{
"id": 2,
"attributes": {
"title": "game2 ",
"description": "jkgbr",
"createdAt": "2022-02-18T21:12:12.108Z",
"updatedAt": "2022-02-18T21:12:12.967Z",
"publishedAt": "2022-02-18T21:12:12.965Z",
"image": {
"data": null
}
}
},
{
"id": 3,
"attributes": {
"title": "game3",
"description": "sqlekjlbkgt",
"createdAt": "2022-02-18T21:16:18.886Z",
"updatedAt": "2022-02-18T21:16:19.996Z",
"publishedAt": "2022-02-18T21:16:19.995Z",
"image": {
"data": null
}
}
},
{
"id": 4,
"attributes": {
"title": "game 4",
"description": "sadjglklasdhbl",
"createdAt": "2022-02-19T06:25:06.589Z",
"updatedAt": "2022-02-19T06:25:07.300Z",
"publishedAt": "2022-02-19T06:25:07.297Z",
"image": {
"data": null
}
}
},
{
"id": 5,
"attributes": {
"title": "game 5 notebook",
"description": "create on notebook",
"createdAt": "2022-02-19T06:46:04.335Z",
"updatedAt": "2022-02-19T06:46:05.471Z",
"publishedAt": "2022-02-19T06:46:05.469Z",
"image": {
"data": null
}
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 5
}
}
}
Can anybody help a total JS newbie on this?
CodePudding user response:
Look at your data. Most of the "post" records have this:
"image": {
"data": null
}
The data
value is null. So when you do this:
post.attributes.image["data"].map(...)
You are trying to call .map()
on null
. Which is what the error is telling you:
Cannot read properties of null (reading 'map')
If the value might be null
, check for null
before using it. For example:
post.attributes.image["data"]?.map(...)
Or more explicitly:
post.attributes.image["data"] ?
post.attributes.image["data"].map(...) :
null
Basically any time you have an object/array that might be null
, you need to make sure that it isn't null
before trying to de-reference it.
In this case I'm assuming that you don't want the code to produce any output when it encounters a null
value. If that's not the case then you can conditionally produce whatever output you like when you encounter a null
reference.
CodePudding user response:
I have checked that in one of your entries in image.data are with a null entry. Check the second entry with id 2
.
{
"id": 2,
"attributes": {
"title": "game2 ",
"description": "jkgbr",
"createdAt": "2022-02-18T21:12:12.108Z",
"updatedAt": "2022-02-18T21:12:12.967Z",
"publishedAt": "2022-02-18T21:12:12.965Z",
"image": {
"data": null
}
}
},
When map tries to read the entire array of images in each post, if it finds a null entry it will break. Something that helps is using the optional chaining operator "?."
in JS. This prevents that if an null or undefined has been found by Array.map it will not break the entire React render.
{post.attributes.image?.["data"]?.map((img) => ())}