How to fill users variable with data from GET request in React - reactjs

I am making a GET call request to an API in order to fetch some data in my React component and save it to my users variable, but the data does not get saved, I get undefined when I console.log it. How can I set the response data from my GET call and save it in the users variable? Here is my attempt:
const [users, setPosts] = React.useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then((data) => console.log(data));
setPosts(users.data);
}, []);

In the code you have posted, you aren't saving the data to users. Try this:
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then(setPosts);
}, []);

This is how it should be do it:
const [users, setPosts] = React.useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.json())
.then((data) => setPosts(data););
}, []);
That way you set your users as data
Also as a hook rule you should define your state as follow const [users, setUsers] = useState()

Related

Troubles with using hook useState()

Trying to use fetched data into hook useState(fetchedData)
const [car, setCar] = useState({images: []});
useEffect( () => {
fetchOneCar(id)
.then(data => setCar(data))
.finally(() => setLoading(false))
},[id]);
const [images,setImages] = useState(car.images)
console.log(images) // -> [] unpredictably empty
console.log(car.images) // -> [{},{},{}] (fetched data)
How to properly set data into useState() in my case ?
ok look first car is {images:[]}
then images is []
and then car turns into whatever data you fetched in use effect
just because you declare useState after use effect doesn't mean it will run after useEffect.
First all the useStates run and then the effects. that's the law.
so there is no unexpected result.
To fix this in yur use effect do this:
useEffect( () => {
fetchOneCar(id)
.then(data => {
setCar(data);
setImages(data)
})
.finally(() => setLoading(false))
},[id]);
According to your code, I expect that you want to fill the images with the result from data. If it is, then you have to put the setImages(data.images) inside the resolved promise, after the setCar(data).
It should be like this one
const [car, setCar] = useState({images: []});
const [images,setImages] = useState();
useEffect( () => {
fetchOneCar(id)
.then(data => {
setCar(data);
setImages(data.images);
})
.finally(() => setLoading(false))
},[id]);
I put the useState() for images at the top for better reading.

navigator.geolocation coords, used as params in the api url, load after the weatherAPI has already been called

I am using navigator.geolocation to get the latitude and longitude of the user. I am then using latitude and longitude as query params to fetch the WeatherAPI so that my website will show the user the weather in his exact town.
The problem is, I can see from the console log that the fetch() function (which I have stored inside useEffect() runs before the navigator.geolocation, resulting in the API fetching me a location with coordinates 0, 0.
I have tried using the fetch inside the geolocation function, as well as async/await, but since it's already inside useEffect, it won't work.
Any ideas on how I could fix this?
const [latitude, setLatitude] = useState(0)
const [longitude, setLongitude] = useState(0)
const [location, setLocation] = useState([])
navigator.geolocation.getCurrentPosition( (position) => {
setLatitude(position.coords.latitude)
setLongitude(position.coords.longitude)
})
useEffect(() => {
fetch(`https://api.weatherapi.com/v1/forecast.json?key=db698b5e650a441fae6190451221401&q=${latitude},${longitude}&days=1&aqi=yes&alerts=yes`)
.then(response => response.json())
.then(data => {
const locationData = data;
setLocation(locationData);
});
}, [])
const [location, setLocation] = useState([])
useEffect(() => {
navigator.geolocation.getCurrentPosition( (position) => {
fetch(`https://api.weatherapi.com/v1/forecast.json?key=db698b5e650a441fae6190451221401&q=${position.coords.latitude},${position.coords.longitude}&days=1&aqi=yes&alerts=yes`)
.then(response => response.json())
.then(data => {
const locationData = data;
setLocation(locationData);
});
})
}, [])

users array hook is not updating with all the list items

So I'm creating a simple MERN App, backend is working properly, but when working with useState hook in frontend is causing issues.
what im trying to do is to fetch "users" data(an array of object with field username) from backend endpoints, and updating the users array which is a hook, but it only updates with the last itm of the incoming username and not list of all usernames!!
code for fetching and updating the hook:
const [users, setUsers] = useState([]);
const getUsers = () => {
fetch("http://localhost:5000/users")
.then(res => res.json())
.then(data => {
console.log(data); //line 17
data.map((itm) => {
console.log([itm.username]) //line 19
setUsers([...users, itm.username])
})
})
.catch(err => console.log(err))
}
useEffect(() => {
getUsers();
}, [])
console.log(users); //line 30
what I want is to get a list of usernames in the "users" state!
something like this:
users = ["spidey", "thor", "ironman", "captain america"]
console.log is also not showing any errors...
console window
pls help, can't figure out where it's getting wrong?
The issue is two-fold, first you are using Array.prototype.map to iterate an array but are issuing unintentional side-effects (the state updates), and second, you are enqueueing state updates in a loop but using standard updates, each subsequent update overwrites the previous so only the last enqueued update is what you see in the next render.
Use either a .forEach to loop over the data and use a functional state update to correctly update from the previous state.
const getUsers = () => {
fetch("http://localhost:5000/users")
.then(res => res.json())
.then(data => {
console.log(data);
data.forEach((itm) => {
console.log([itm.username]);
setUsers(users => [...users, itm.username]);
})
})
.catch(err => console.log(err));
}
Or use the .map and just map data to the array you want to append to the users state.
const getUsers = () => {
fetch("http://localhost:5000/users")
.then(res => res.json())
.then(data => {
console.log(data);
setUsers(users => users.concat(data.map(itm => itm.username)));
})
.catch(err => console.log(err));
}
you can set the map result in a variable after that you can call the useState on it.
const [users, setUsers] = useState([]);
const getUsers = () => {
fetch("http://localhost:5000/users")
.then(res => res.json())
.then(data => {
console.log(data); //line 17
const userNameData = data.map(itm => itm.username)
setUsers(...users, userNameData)
})
.catch(err => console.log(err))
}
useEffect(() => {
getUsers();
}, [])
console.log(users);

I am facing a problem of fetching data (React, useEffect)

I am trying to fetch data from the URL given below, sometimes I am getting but most of the time not in the console. I don't know about the problem I have tried with async-await but the result was the same.
https://quiet-forest-82433.herokuapp.com/myorders/?email=liza#liza.com
My code is:
const {user} = useAuth();
const [totalCart, setTotalCart] = useState({})
useEffect(() => {
const url = `https://quiet-forest-82433.herokuapp.com/myorders/?email=${user?.email}`
fetch(url)
.then(res => res.json())
.then(data => console.log(data))
}, []);
useEffect should have a dependency on user.
And don't call fetch until you have a valid user email. Currently, you're code will ask for email=undefined until the user populates, but the useEffect() will not fire again because there is no dependency on user.
useEffect(() => {
if (!user || !user.email) return
const url = `https://quiet-forest-82433.herokuapp.com/myorders/?email=${user?.email}`
fetch(url)
.then(res => res.json())
.then(data => console.log(data))
}, [user]);

How to assign data to a variable from axios get() response

I am trying to use Express (axios) to build a React app.
I was able to get an array of objects from MongoDB using get() method. Currently the list is printed out to the console. How can I assign it to a variable so that I could use that array for further actions?
useEffect(() => {
const expensesListResp = async () => {
await axios.get('http://localhost:4000/app/expenseslist')
.then(
response => console.log(response.data))
}
expensesListResp();
}, []);
Many thanks!
You can assign it in the following way, let say you have an array posts:
const [posts, setPosts] = useState([]);
useEffect(() => {
axios.get('url')
.then(res => setPosts(res.data))
.catch(err => console.log(err));
}, [])
In your code, you can do it in this way:
const [resultArray, setResultArray] = useState([]);
useEffect(() => {
const expensesListResp = async () => {
await axios.get('http://localhost:4000/app/expenseslist')
.then(
response => setResultArray(response.data))
}
expensesListResp();
}, []);
I am assuming that you have data printed on the console.log(response.data) and you want it to be assigned to a variable so that you can use it right?
if that's the case you are already using async function just name it with whatever variable name you want it to be before await.
for example:
const expensesListResp = async () => {
const "your variable name" = await axios.get('http://localhost:4000/app/expenseslist')
}
you can also save that variable in your state, if you want to use that variable data throughout your application.

Resources