Axios only fetches Azure API response ONCE - reactjs

I am trying to fetch my blobs with axios inside my React app using the Azure REST API (and parse it to JSON as it comes in as a XML response). Problem here is that it fetches correctly once, and when the page is refreshed it does not fetch anything else, showing undefined whenever I try to access any of the data, and returning empty array in console... what am I doing wrong?
const [images, setImgs] = useState([])
useEffect(() => {
const fetchData = async () => {
const response = await axios.get(`https://${process.env.AZURE_SPACE}.blob.core.windows.net/${process.env.AZURE_CONTAINER}?restype=container&comp=list&${process.env.AZURE_TOKEN}`);
const newJson = JSON.parse(convert.xml2json(response.data, {compact: true, spaces: 4}))
setImgs(newJson);
}
fetchData();
console.log(images)
}, []);

Try
await fetchData();
Otherwise, your console log is called before the answer coming back from azure

So, if you checking console.log(images) why this is still blank :
setImgs(newJson); // is also async
fetchData();
console.log(images) //<-- So it won't reflected immediately right after fetchData()
But your DOM will get updated, you can confirm it.
You can run the below snippet and check HTML and conosle.log both :
setUsers([...users, "Vivan" , "Darshita"]); // is async
console.log(users); // Due to setUsers's async behaviour it still console.log old values
const { useState , useEffect } = React;
const App = () => {
const [users,setUsers] = useState(['Vivek' , 'Darsh']);
useEffect(() => {
setTimeout(() => {
setUsers([...users, "Vivan" , "Darshita"]);
console.log(users);
},2000);
},[]);
return (
<div>
{ users.map(user => <p>{user}</p>) }
</div>
);
}
ReactDOM.render(<App />, document.getElementById('react-root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react-root"></div>

So it sounds like two separate questions.
How to solve the await issue:
const [images, setImgs] = useState([])
useEffect(() => {
const wrapperFunc = async () => {
const fetchData = async () => {
const response = await axios.get(`https://${process.env.AZURE_SPACE}.blob.core.windows.net/${process.env.AZURE_CONTAINER}?restype=container&comp=list&${process.env.AZURE_TOKEN}`);
const newJson = JSON.parse(convert.xml2json(response.data, {compact: true, spaces: 4}))
setImgs(newJson);
}
await fetchData();
console.log(images)
};
wrapperFunc();
}, []);
The code inside the wrapperFunc can now wait for fetchData to return before writing to the console.
The second issue where it is only getting called once. It could be fixed as a result of this new code. However, I ran into something similar with React Hot Loading where the gating state was already set, so it would rerun my new code. I had to just change the state manually and then the code ran.

Related

Infinite Loop React

I'm new in React, and i have problems to show the content of an array.
I have a state to store the data (initial value []). Then, I have a function to consume frmo an api with a get, then i store that data in the state, and finally, I iterate over the state to show it on the page. Everything's is ok, the function gives return the values, but in the console, the return is enter in a infinite loop, slowing down the browser.
Here I detach the code
The state where i store the values
const [projects, setProjects] = useState([]);
Function that consumes the api and save it in the state
const getData = async () => {
let allProjects = {};
const res = await axios.get(URL_BASE);
allProjects = res.data;
setProjects(allProjects);
console.log(projects);
};
useEffect to refresh the render when projects is change
useEffect(() => {
getData();
}, [projects]);
This is where i iterate
return (
<div>
<p>La cantidadd de proyectos en total son:</p>
{getData() && projects.map((proyecto) => <div>{proyecto.titulo}</div>)}
</div>
);
This useEffect basically says "any time projects changes, run getData()":
useEffect(() => {
getData();
}, [projects]);
And running getData() changes projects:
const getData = async () => {
//...
setProjects(allProjects);
//...
};
Thus the endless cycle.
It sounds like you just want to getData() once, when the component first loads. For that you can just use an empty dependency array:
useEffect(() => {
getData();
}, []);

state value is undefine in react js

I get the data from the backend and store it into the state (post). when I use post.name then it shows undefined.
const [post, setPost] = useState([]);
const getAllUser = async () => {
const response = await fetch("http://localhost:4000/getpost");
response.json().then((res) => setPost(res.data.Post));
// console.log(post);
};
useEffect(() => {
getAllUser();
}, []);
const component = post.component; // value is undefine
console.log(component);
In the pass I used the setState callback so now you might like to use:
https://maksimrv.medium.com/usestate-with-callback-d574298eb8bd
because you want to read a state variable's value immediately after it has been updated.
You need to validate if post is populated before accessing post.name.
If you're using babel, you can do it like this:
post?.name
If you're not using babel:
post ? post.name : 'empty'
Try and handle all your async logic in useEffect
useEffect(() => {
getAllUser();
async function getAllUser () {
const response = fetch("http://localhost:4000/getpost");
const json = await response.json()
setPost(json.data.Post);
// console.log(post);
};
}, []);
When you're manipulating the state, you should use useEffect(), for instance:
useEffect(() => {
// Do something with the updated post object here.
}, [ post ]);

I want to display API data on first load in React

I can see that the data is being console logged but in my return statement it doesn't render and the data is null. I am well aware that before I get the data the page is being rendered first. How can I make it render after it has received the data?
const [bookingData, setBookingData] = useState(null);
const url = 'http://127.0.0.1:8000/api/test/api'
useEffect(() => {
fetchData();
console.log(bookingData)
}, []);
function fetchData() {
axios.get(url).then((response) => {
console.log(response.data.data[0])
setBookingData(response.data.data[0])
});
}
return (
<div> {bookingData.tracking_id} </div>
);
Since fetching data from an API is an asyncronous function, you'll have to use an async function.
async function fetchData () {
axios.get(url).then((response) => {
console.log(response.data.data[0])
setBookingData(response.data.data[0])
});
}

Why is my React useEffect not loading again when I refresh the page?

I am using a useEffect to get information from firebase and set my redux state thereafter. When I open the page for the first time, all my components contain the correct information. As soon as I refresh the page, all the information is set to nothing? I think it is because the useEffect does not execute again for some reason. Here is my code below:
useEffect(async () => {
setLoading(true);
const fetchData = async () => {
await getConfigs().then((response) => {
const obj = response;
setRedux(obj[0]);
});
};
fetchData();
}, []);
I think the problem is that you provide an async function as a callback to useEffect, which is not allowed. Just get rid of it, like so:
useEffect(() => {
setLoading(true);
const fetchData = async () => {
// Also, you either await or use .then(), not both
const response = await getConfigs();
const obj = response;
setRedux(obj[0]);
};
fetchData();
}, []);

Can't have my data from firebase after get method with reactjs

Hello i take data from realtime database in firebase with this way.
useEffect(() => {
async function asyncCall() {
const myurl = await axios.get("https://mysiteproject- 8adcf.firebaseio.com/products.json")
setUrl(myurl)
}
asyncCall();
},[]);
The result of when i
console.log(url)
showing in the below image
When i
console.log(url.data)
this is shown up
That is the data i want to map. But when i
console.log(url.data.id)
this is shown up in my console
Can anyone tell me why this happening.
Also i try this in my code
useEffect(() => {
async function asyncCall() {
const myurl = await axios.get("https://mysiteproject-8adcf.firebaseio.com/products.json")
setUrl(myurl)
}
asyncCall();
},[]);
let myvar = url.data;
console.log(myvar);
{myvar.map((myvar => (
console.log(myvar.id)
)))}
But again i have a error
Can anyone help me with this??
You should add check if url.data is exists. When you render console.log(myvar); - url.data is undefined because you didn't get it from the server yet. So your code should looks like this:
useEffect(() => {
async function asyncCall() {
const myurl = await axios.get(
"https://mysiteproject-8adcf.firebaseio.com/products.json"
);
setUrl(myurl);
}
asyncCall();
}, []);
if (url.data) {
let myvar = url.data;
console.log(myvar);
myvar.map((myvar) => console.log(myvar.id));
}
When you'll get url.data the component will be updated because you update state via setUrl and the data will be logged to console.

Resources