How To Have Multiple Axios inside UseEffect That Doesnt Turn Error? - reactjs

I need 3 axios :
to detect token, so I know which user is logged in. This is so that I can have a "userid" that I can pass for my other axios endpoints
the list of orders : returns an array of all the order history of that user
the data of the user, such as first_name, last_name, email etc
here is how it looks like:
const cookies = new Cookies();
const token = cookies.get("jwtToken");
const [user_detail, setuser_detail] = useState({});
const [userid, setuserid] = useState(null);
const [refresh, setrefresh] = useState(false);
const [orderData, setorderData] = useState([]);
const [userData, setuserData] = useState({});
useEffect(() => {
axios
.get(`http://localhost:3001/auth/token/decode/${token}`)
.then((result) => {
setuser_detail(result.data.user_detail);
setuserid(result.data.user_detail.user_id);
setrefresh(!refresh);
});
}, []);
useEffect(() => {
axios
.get(`http://localhost:3001/users/orders/${userid}`)
.then((res) => {
setorderData(res.data);
})
.catch((err) => console.log(err));
axios.get(`http://localhost:3001/users/detail/${userid}`).then((res) => {
setuserData(res.data[0]);
});
}, [refresh]);
If there is only the useEffect for Token and Orders, it works fine. However when I added the 3rd (user details) useEffect, it doesn't seem to want to receive the response. It will show only if I saved my react file, and then (without restarting my npm start) add the 3rd useEffect. It works until I refresh it, and it returns "TypeError: Cannot read property 'first_name' of undefined". Which doesn't make sense because if I don't refresh it, the first_name can in fact be rendered. I am pretty confused.

Use a single useEffect for onComponentMount, and create an async function inside your useEffect to handle your axios calls.
useEffect(() => {
async callAxios() => {
const result = await axios.get(`${url_one}`)
const user_orders = await axios.get(`${url_two}`)
const user_details = await axios.get(`${url_three}`)
}
callAxios()
}, [])

Related

useEffect is causing infinite loop when use state as dependency

Here simply I am fetching data from mysql DB and storing it in state and in order to fetch this data:
const [orders, setOrders] = useState([]);
To fetch data I am using different functions and finally I am calling those functions using useEffect simple enough and so for everything is working perfectly but the problem comes whenever I use the state as dependency where I am storing data beacause if I dont do that then I have to manually refresh the page for latest changes and I have tried every given solution on stackoverflow but any of the solution didnt work so someone can please help me how can I use this state as dependencey without causing infinite loop:
const [orders, setOrders] = useState([]);
const loadData = async () => {
const response = await fetch("http://localhost/k-shop/load.php");
const result = await response.json();
setOrders(result);
};
const loadTotal = async () => {
const response = await fetch("http://localhost/k-shop/amount.php");
const result = await response.json();
setTotal(result);
};
useEffect(() => {
loadData();
loadTotal();
}, [orders]);
console.log(orders);
If you move the state into the useEffect dependency, you can then check if it is empty, and only set it when that check passes.
It will set the state once to populate and not pass the check again.
const [orders, setOrders] = useState([]);
const loadData = async () => {
const response = await fetch("http://localhost/k-shop/load.php");
const result = await response.json();
setOrders(result);
};
const loadTotal = async () => {
const response = await fetch("http://localhost/k-shop/amount.php");
const result = await response.json();
setTotal(result);
};
useEffect(() => {
if(orders.length === 0) {
loadData();
}
// you can do the same with checking loadTotal() state
}, [orders]);
console.log(orders);
Avoid ,non-primitive data types in dependencyArray ,
useEffect(() => {
loadTotal();
loadData();
}, [total, orders.length]);
every times you "setOrders" means you change the state,every times you change the state,means the "useEffect" will do again.that cause infinite loops.why not try useEffect(() => {loadData()}, [])?

react page doesnt render when getting the data back from server

react won't work when rendering the page, but when i changed code in the vscode (added a line of console or comment one line out), the page is rendered. or when page is not rendered. when i hit refresh. i can see some of my content but it won't render. the usestate doesnt seem like to successfully save the value
const ParkDetail = () => {
const [parkId, setParkId] = useState('')
const [park, setpark] = useState('')
const [areas, setAreas] = useState([])
const [ridesName, setridesName] = useState([])
const [rides, setrides] = useState([])
let { id } = useParams()
console.log(id)
useEffect(() => {
async function getPark() {
try {
await setParkId(id)
const res = await axios.get(`/parks/details/${parkId}`)
console.log(res)
const park1 = await res.data.park
console.log(park1)
await setpark(park1)
console.log(park)
await setAreas(park1.serviceAnimalRelief)
// await setridesName(park1.topRides)
// console.log(ridesName)
} catch (e) {
console.log(e.message)
}
}
getPark()
}, [parkId])
}
I believe the problem is you using the state as parameters in your get requests. Since state setter functions do not return promises, using await on them is basically of no use. You should rather use the variables that you obtain from the get requests directly. For example, use id instead of parkId and so on.

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.

Infinite Loop on API GET Requests

I'm relatively new to working with APIs and I'm looking to fetch data from an API using a GET request and this code is causing an infinite loop of GET requests. What I'm ultimately looking to accomplish is to access the data I'm receiving in res.data so I can pull information from the object that's being returned in the API response (using something like res.data.name which is currently prompting an error saying res is not defined which I believe could be due to a scope issue).
const Podcast=()=>{
const[show,setShow]=useState([])
const[bestPodcasts,setBestPodcasts]=useState([])
const [genre,setGenre]=useState('')
const[data,setData]=useState({})
client.fetchBestPodcasts(
{ genre_id: '91',
page: 2,
region: 'us',
safe_mode: 0,}
)
.then((res) => {
setData(res.data)
// Get response json data here
console.log(res.data);
}).catch((error) => {
console.log(error)
})
You can make use of useEffect hook, this shall call your API only once/initially:
const Podcast = () => {
const [show, setShow] = useState([])
const [bestPodcasts, setBestPodcasts] = useState([])
const [genre, setGenre] = useState('')
const [data, setData] = useState({})
useEffect(() => {
apiCall()
}, []);
const apiCall = () => {
const data = {
genre_id: '91',
page: 2,
region: 'us',
safe_mode: 0
}
client.fetchBestPodcasts(data)
.then(res => setData(res.data))
.catch(error => console.log(error))
}
}

useEffect not triggering but the template is being rendered somehow

I am getting too many re-renders while using react-hooks.
I am trying to fetch data from api by using a parameter in URL.
Here's the code:
export default function Details() {
const { title } = useParams();
const [loading, setLoading] = useState(true);
const [details, setDetails] = useState([]);
const [error, setError] = useState("");
function getDetails(keyword) {
if (keyword) {
setLoading(true);
fetch(
`API`
)
.then((res) => {
let result = res.data.results;
result = result.filter(function (result) {
return (result.title = keyword);
});
setDetails(result[0]);
setLoading(false);
console.log(details);
})
.catch((err) => {
setError(["Unable to fetch data"]);
setLoading(false);
});
}
}
getDetails(title)
return(
// template
)
now I think this is happening at the line where I call getDetails.
then I tried using useEffect to load the data only once after it is mounted,
useEffect(() => {
getDetails(title);
}, []);
It still is unable to fetch the data, as the getDetails function is never called.
How can I resolve this?
Edit:
Fixed one silly error.
Here's the codesandbox link:
Codesandbox
There are multiple issues with this, first you need to specify what you want to be notified about when the useEffect gets called again. You could do this by adding the variables you want within the array
useEffect(() => {
getDetails(title);
}, [
// Add what you want here
]);
The second issue you have is that you declared the detalis variable twice. Once using the set state here: const [details, setDetails] = useState([]);
The second time here:
const details = getDetails(title)
the code here has two obvious error beside the functionality problems you mentioned:
1 - you cannot declare two variables with same name using let or const; it will throw a SyntaxError
const [details, setDetails] = useState([]);
...
const details = getDetails(title)
2- getDetails function is written with a asynchronous mindset, and it will return nothing,
so details in const details = getDetails(title) will be set to undefined
Looks like your getDetails function has title param so I would add title and getDetails both in the dependency list of useEffects
Or place getDetails inside the useEffect
Here is your working code. You had multiple problems where res.data was undefined so you need to get res.results directly based on your response object
useEffect(() => {
function getDetails(keyword) {
if (keyword) {
setLoading(true);
fetch(
`https://api.jikan.moe/v3/search/anime?q=${keyword}&page=1&genre_exclude=0`
)
.then((res) => res.json())
.then((res) => {
console.log(res.results);
let result = res.results;
console.log(result);
result = result.filter(function (result) {
return (result.title = keyword);
});
setDetails(result[0]);
setLoading(false);
console.log(3);
})
.catch((err) => {
console.log(err);
setError(["Unable to fetch data"]);
setLoading(false);
});
}
}
console.log('calling getDetails')
getDetails(title);
}, [title]);
Note: tested in the code sandbox link provided in the question. Its working code.

Resources