How could i solve the problem for Javascript Fetch - javascript

Below committed code is axios. Which is working fine. But javascript fetch is not working. Let me know what is the issue in the code. How to fix it. Please explain it in a simple way. Thanks!
import React, {useEffect, useState} from 'react'
import axios from 'axios'
function Datafetching() {
const [posts, setposts] = useState([])
const getMovieRequest = async () => {
const url = `http://jsonplaceholder.typicode.com/posts`;
const response = await fetch(url);
const responseJson = await response.json()
if (responseJson.data){
setposts(responseJson.data)
console.log(responseJson.data)
}
}
useEffect(() => {
// axios.get('http://jsonplaceholder.typicode.com/posts')
// .then(res => {
// console.log(res)
// setposts(res.data)
// })
// .catch(err => {
// console.log(err)
// })
getMovieRequest()
})
return (
<div>
<ul>{
posts.map(post => <li key={post.id}>{post.title}</li>)
}
</ul>
</div>
)
}
export default Datafetching

responseData contains the data as array, not responseData.data:
if (responseJson){
setposts(responseJson)
console.log(responseJson)
}

Related

Fetching multipule endpoints at one return undefined

import React, { useEffect, useState } from "react";
import { endpoint, apiKey } from "../api";
import Container from "../components/layouts/Container";
export default function Movie({ route }) {
const { movieId } = route.params;
const [movieDetails, setMovieDetails] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const urls = [
`${endpoint}/movie/${movieId}?api_key=${apiKey}`,
`${endpoint}/movie/${movieId}/credits?api_key=${apiKey}`,
`${endpoint}/movie/${movieId}/images?api_key=${apiKey}`,
`${endpoint}/movie/${movieId}/reviews?api_key=${apiKey}`,
`${endpoint}/movie/${movieId}/similar?api_key=${apiKey}`,
];
useEffect(() => {
const fetchData = () => {
setIsLoading(true);
Promise.all(
urls.map((url) => {
return fetch(url);
})
)
.then((response) => {
return Promise.all(response.map((res) => res.json()));
})
.then((data) => {
setMovieDetails(data);
setIsLoading(false);
})
.catch((err) => {
console.log(err);
});
};
fetchData();
}, []);
console.log(movieDetails[0]);
Hello,
I've encountered a problem tha that when i try to fetch the request above when i console.log() it it first returns undefined and then return the desired response.
The response is expected as initially the state is undefined.
During the request also, till the response is unresolved, the process is suspended and the state stays undefined.
A simple solve will be to move the console.log(movieDetails[0]) into the last .then() body or you could write your own Promise resolution functions.

Why does copies of the same API call returned undefined for one function and works for the other

While trying to use TMDB API in my project I ran into an issue that I am unable to figure out. I use copies of the same code as shown below in two different files and functions - one works, and the other one returned undefined for some reason. Can you please point out what I am not doing right, I need fresh new eyes on this. Thank you
import Head from 'next/head';
import React from 'react';
import { useState, useEffect } from 'react';
import Link from 'next/link';
import styles from '../styles/Home.module.css';
export const getServerSideProps = async () => {
const movieApi = process.env.TMDB_API_KEY;
const res = await fetch(`https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=${movieApi}&page=1`);
const movie_data = await res.json();
return {
props: {
movies : movie_data
},
}
}
const Form = ({movies}) => {
console.log(movies); //returns "Undefined"
const [search, Setsearch] = useState("");
//Handle input value
const getLocation = async (e) => {
// console.log(e.target.value)
e.preventDefault();
}
//Handle Submit
const handleSubmit = (event) =>{
// console.log("clicked")
event.preventDefault();
}
export const getServerSideProps = async () => {
const movieApi = process.env.TMDB_API_KEY;
const res = await fetch(`https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=${movieApi}&page=1`);
const movie_data = await res.json();
return {
props: {
movies : movie_data
},
}
}
export default function Home({movies}) {
console.log(movies); //works perdectly
const [session, loading] = useSession();
const tmdbMpviesResults = movies.results
As per your comment, <Form /> is not a page. Exactly that is your problem:
getServerSideProps can only be exported from a page. You can’t export it from non-page files.

Why isn't the element getting rendered even though there is no syntax error nor warning?

I have fetched the top 30 teams in CSGO from the Hltv API. The data is stored inside the team variable and I use a map function in order to get the individual teams names from the array and render it. However, it currently is not rendering anything.
import React from 'react';
import './App.css';
import HLTV from 'hltv';
function App() {
const get = async () => {
return await HLTV.getTeamRanking()
.then(res => Object.entries(res))
.catch(err => console.log(err));
}
const teamNames = [];
(async () => {
const teams = await get();
teams.map(x => {
teamNames.push(x[1].team.name);
});
teamNames.map(team => {
console.log(team);
})
})();
return (
<ul>
{teamNames.map(team => <li>{team}</li>)}
</ul>
)
}
export default App;
React doesn't know that the teamMates variable is being updated. In order to let React know about a change in the variable, you should either fetch the data before rendering the component or use useState with useEffect.
You can read the useState documentation for more information.
import React, { useState, useEffect } from 'react';
import './App.css';
import HLTV from 'hltv';
const get = async () => {
return await HLTV.getTeamRanking()
.then(res => Object.entries(res))
.catch(err => console.log(err));
}
function App() {
const [teamNames, setTeamNames] = useState([]);
useEffect(() => {
get().then(teams => {
setTeamNames(teams.map(x => x[1].team.name));
});
}, []);
return (
<ul>
{teamNames.map(team => <li>{team}</li>)}
</ul>
)
}
It won't render because the results arrive too late for the initial render. Change teamNames to be stateful, e.g. const [teamNames, setTeamNames ] = useState([]). Then update the incoming result with setTeamNames. And instead of an IIFE (Immediately Invoked Function Expression), use useEffect(() => {...}).
For example:
function App() {
const [teamNames, setTeamNames] = useState([]);
React.useEffect(() => {
const fetchTeamRankings = async () => {
return HLTV.getTeamRanking()
.then(res => Object.entries(res))
.catch(err => console.log(err));
};
fetchTeamRankings().then(result => setTeamNames(result.map( r => r[1].team.name )));
}, [setTeamNames]);
return (
<ul>
{teamNames.map(team => <li>{team}</li>)}
</ul>
)
}

why is match undefined in fetch function

I'm using match to pull an ID that will search an API for that ID and pull data from it. This was working until I started moving my files around and now I'm not sure how to pass match into my fetch function
HeroDetail.services
import React from 'react'
export const fetchHeroDetail = async ({match}) => {
const data = await fetch(`https://api.opendota.com/api/heroStats`)
const item = await data.json()
const heroId = match.params.id
console.log(match.params.id)
const hero = item.find(element => element.id === Number(heroId))
console.log(hero)
return await hero
};
HeroDetail Component
import React, {useState, useEffect} from "react"
import "../App.css"
import {fetchHeroDetail} from './services/HeroDetail.services'
const setHeroDetail = async setHero => {
const hero = await fetchHeroDetail()
setHero(hero)
}
function HeroDetail() {
const [hero, setHero] = useState({})
useEffect(() => {
setHeroDetail(setHero)
},[])
return(
<div>
<h1>{hero.localized_name} </h1>
<h2>{hero.move_speed}</h2>
<h2>{hero.base_health}</h2>
</div>
)
}
export default HeroDetail
You should just do this:
function HeroDetail() {
const [hero, setHero] = useState({})
useEffect(async () => {
if (!hero) {
const data = await fetchHeroDetail()
setHero(data)
}
})
...
}

Unable to copy array using setstate hook

I am fetching data from backend using axios whenever I am trying to update hooks it is not updating.
The data is JSON from where I am extracting data and trying to set element. It might sound silly but can somebody tell me what is dependent array?
I keep getting this
Line 18: React Hook useEffect has a missing dependency: 'elements'. Either include it or remove the dependency array react-hooks/exhaustive-deps
Here is code
import React, { useEffect, useState } from 'react';
import './App.css';
import axios from 'axios';
function App() {
const [elements, setElements] = useState([]);
useEffect(() => {
const res = async () => {
const result = await axios.get('/data');
const data = result.data;
console.log(data);
setElements(elements => [...elements, data]);
console.log(elements);
};
res();
}, []);
console.log(elements.map(element => console.log(element)));
return <div className='App'>Hello</div>;
}
export default App;
Just console.log outside your effect. You're already using the updater version of useState
setElements(elements => [...elements, data])
The missing dependecy warning is coming from console.log(elements)
import React, { useEffect, useState } from 'react';
import './App.css';
import axios from 'axios';
function App() {
const [elements, setElements] = useState([]);
useEffect(() => {
const res = async () => {
const result = await axios.get('/data');
const data = result.data;
console.log(data);
setElements(elements => [...elements, data]);
};
res();
}, []);
console.log(elements);
return <div className='App'>Hello</div>;
}
export default App;
Missing dependency warning is because you use console.log(elements) inside the useEffect.
And your elements log is not showing latest result because state is not changed (yet)
Just add a useEffect to keep track of elements changes like below.
function App() {
const [elements, setElements] = useState([]);
useEffect(() => {
const res = async () => {
const result = await axios.get('/data');
const data = result.data;
console.log(data);
setElements(elements => [...elements, data]);
};
res();
}, []);
useEffect(() => console.log(elements), [elements])
return <div className='App'>Hello</div>;
}
export default App;
To answer your question;
The dependency array is their to let React know when the useEffect in this case should be triggered. So the useEffect i added, only triggers when its dependency elements is changed.
In your case you are puting the array data inside elements, setElements(elements => [...elements, data]); so it will be array inside array.
Try the below :
function App() {
const [elements, setElements] = useState([]);
useEffect(() => {
const res = async () => {
const result = await axios.get('/data');
const data = result.data;
console.log(data);
setElements([...elements, data]);
};
res();
}, []);
useEffect(() => console.log(elements), [elements])
return <div className='App'>Hello</div>;
}
export default App;

Categories