Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
107
rated 0 times [  110] [ 3]  / answers: 1 / hits: 11349  / 4 Years ago, tue, september 15, 2020, 12:00:00

I am building a detail's page to display the details of a selected object within my json file.
(click on a thumbnail image that takes you to the video page, which includes the video's details)


So far, I have 1) The data file 2) The home page where you will select the item you want to see more information off 3) The page that displays the information.


However, I have not been able to display any json data on the details page. I have tried using the "match" method, I used Request.URL(), both which did not work, but I think the right way to do it is with the useEffect hook (please correct me if I am wrong)


This is what I have at the moment with the useEffect route:


pages/FeaturedVideo.js:


import videos from '../../data/data.json'

const FeaturedVideo = () => {

const [videos, setVideos] = useState(null);

useEffect(() => {
let url = "/src/data/data.json";
fetch(url)
.then(res => res.json())
.then(videos => setVideos(videos))
}, []);


return(
<div>
<p>The video and it's details will go here </p>
{videos.id.map((video) =>{
<div key={video.id} {...videos}></div>
})}
</div>
)
}

export default FeaturedVideo;

What I am trying to do above is to use fetch to call the json file as if it were an API. And then map out the data from the specific video id.


The json file is structured in the following way:


[
{
"id": 2,
"firstLogo": "Minecraft",
"thumbnail": "Thumbnail",
"available": "Unlock 12/6",
"sample": "https://www.youtube.com/watch?v=c_dG_HxHMVI"
},
{
"id": 3,
"firstLogo": "Batman",
"thumbnail": "Thumbnail",
"available": "Unlock 12/13",
"sample": "https://www.youtube.com/watch?v=c_dG_HxHMVI"
}
]

The :id of the video is included into the path in the following way:


<Router>
<Navbar/>
<Switch>
<Route path="/:videoID">
<FeaturedVideo/>
</Route>
<Route exact path="/">
<Home />
</Route>
</Switch>
<Footer />
</Router>

```re

More From » json

 Answers
1

There's a couple of problems with this snippet:


{videos.id.map((video) => {
<div key={video.id} {...videos}></div>
})}


  1. In your code the videos variable is initially null, and then (after fetching) — an array. Arrays don't have id property, and accessing properties of null is an illegal operation. You might want to first ensure that this is an array, rather than null, and then also remove the ".id" part.



  2. You don't return anything from .map()! Yes, you create a JSX element for each item of the array, but they are destroyed unused after that.




Consider using this instead:


{videos && videos.map((video) => (
<div key={video.id} {...videos}></div>
))}



Another problem is with variables' visibility:


import videos from "./path/to/data.json";
// and then later
const [ videos, setVideos ] = useState(null);

That first variable videos (the imported one) is not visible anymore, it got shadowed by the second one.


You either rename the second variable to prevent shadowing, or remove the first one completely as it is unused.




Next thing that I can see is that the code can't make up its mind about what it is actually trying to accomplish. On one hand, router provides an ID to a specific, particular video, which means that we're trying to show only one video. On the other hand though, the FeaturedVideo component is almost a perfect fit for showing the list of all the videos.


Judging from the names and overall setup though, it is somewhat clear that you're trying to show one video, not the whole list.


Looks like you're using react-router. If that's true, in FeaturedVideo you need to access the video ID, provided by router. Given that it is v5+, you can use useParams hook for that:


import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router';

const [ video, setVideo ] = useState(null); // 'video', not 'videos'
const { videoID } = useParams();

useEffect(() => {
fetch("/src/data/data.json")
.then((res) => res.json())
.then((videos) => videos.filter((video) => {
return video.id === videoID;
}))
.then((matched) => setVideo(matched[0]));
}, []);

// Here `video` variable holds either `null` or the first matched array item.
// Render it using suggestions above.



References:



[#2676] Friday, September 11, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
collinisaaka

Total Points: 194
Total Questions: 105
Total Answers: 104

Location: Tonga
Member since Tue, Nov 30, 2021
3 Years ago
;