I am trying to retrieve some data from an API in my react app. When I view the endpoint in FireFox there is an value _embedded, which is what I need, but when I access that endpoint in the react app, it is not there:
Firefox, viewing /wp-json/wp/v2/product?per_page=100&_embed :
When i view the endpoint via console.log in Inspector, viewing /wp/v2/product?per_page=100&_embed :
Is there something that I am missing?
Update:
I am using the following in React:
const Component = ({ state, actions }) => {
const [products, setProducts] = useState([]);
useEffect(() => {
fetch(state.source.api + "/wp/v2/product?per_page=100&_embed")
.then((response) => response.json())
.then((data) => {
setProducts(data);
});
}, []);
Related
I am new to react & JS. I need to sync data to db and use what i got from db render to UI.
Flow: CRUD in infra => sync data to db => use data from db and render to UI.
But the second function always completes first when syncDB still in status "pending". So if I detete all my db and run in very first time, I will get nothing in UI.
This is how I code:
[Sync data to db]
useEffect(async () => {
const syncDB = async () => {
await Api.post(syncLocalDisk({vpcId, instanceId}))
}
syncDB()
}, [])
const {data, isLoading, isRefetching, error, refetch} = useQuery(
['instance-storages', vpcId, instanceId],
() => {
const url = `${instanceStorages({
vpcId,
instanceId,
})}`
return Api.get(url)
},
)
How can I make sure it's syncDB first?
I have tried sync DB inside useQuery but it does not seems very logicial.
useEffect(async () => {
const syncDB = async () => {
await Api.post(syncLocalDisk({vpcId, instanceId}))
}
await syncDB()
}, [])
Try this.
I have a JSON file called teams.json that contains the basic structure ("name", "age", "country", "role", "team", and "image") in an object. I'm using React to use the function fetch() to retrieve the data from the local JSON file. When I call the useEffect (shown below) hook, the data is retrieved from the local JSON file and I'm able call a useState function to store the data in a state variable called data.
useEffect() function call
//file path
filePath = "/src/public/teams.json"
const getData = (file) => {
fetch(file)
.then(res => res.json())
.then(data => setData(data))
.catch(err => console.log("Error fetching data", err)
}
useEffect(() => {
getData(filePath)
}, [filePath])
If I try to edit or access data within the useEffect() hook, the data is able to be retrieved without any problems, as such.
.then(data => console.log(data[0]))
This returns a json object that contains the necessary information.
{
"name":"R",
"image":"https://example.com",
"team":"B",
"role":"WB",
"country":"American",
"age":18
}
However, in the main body of my react App, if I try to obtain data from the data state, it gives me an error saying Cannot read properties of undefined, shown below.
Body of React App
return (
<main>
{data[0].country}
</main>
)
But I get this error:
I've tried solutions to previous forums from:
Stack Overflow Discussion Axios
Stack Overflow Discussion Error Axios
I've moved my project to the structure:
-src
--public
*some files*
and put the JSON file in the public folder. It reads it now but still doesn't render. I've also tried using axios but to no avail.
If this is an easy fix, sorry about that! Thanks for your help!
Because the data isn't loaded yet.
Assuming your app is something like
function App() {
const [data, setData] = React.useState();
const getData = (file) => {
fetch(file)
.then((res) => res.json())
.then((data) => setData(data))
.catch((err) => console.log("Error fetching data", err));
};
useEffect(() => {
getData(filePath);
}, [filePath]);
return <main>{data[0].country}</main>;
}
you're starting off with an undefined data.
Add a guard against that:
if(!data) return <>Loading...</>;
return <main>{data[0].country}</main>;
I'm building a web application that consumes TMDB Api. I have the following code that fetch all information about a TV Show
export const useShowInfoFetch = ({showId}) => {
const [data, setData] = useState({})
const [loading, setLoading] = useState(false)
const [_error, _setError] = useState(false)
const fetchShowInfo = useCallback(() => {
setLoading(true)
try {
axios.get(getShowInfo(showId))
.then(response => {
setData(response.data)
})
} catch (error) {
_setError(true)
} finally {
setLoading(false)
}
}, [showId])
useEffect(() => {
fetchShowInfo()
}, [fetchShowInfo])
return [data, loading, _error]
}
All the information fetched is displayed in page, that also has Links with react-router-dom. Those links goes to another tv show page.
The problem is that when I'm in a page with a tv show that has X amount of seasons and I click a tv show with less seasons, the seasons from the page I was are persisting for a little bit of time. So, when I fetch the information for each season I got a 404 in the page that has less seasons.
Here is a screenshot of the error
The orange circle is what it's displayed since I click the tv show with less seasons.
As you can see, the seasons from the previous page are persisting for a little time, and because The Alienist has only 2 seasons (not 9) I get the 404. You can also note that latter, the correct amount of seasons are displayed.
I've tried to add a cleanup method in the useEffect hook. Something like this:
useEffect(() => {
fetchShowInfo()
return function cleanup() {
setData({})
}
}, [fetchShowInfo])
But this did not work.
I know that I can handle that with a catch after the then Axios promise, but I want to figure out why this is happening and fix the issue with a good solution instead of avoiding it.
Any help is welcomed and I can share the repository with all the code if needed.
EDIT:
To display the similar movies I use another custom hook
export const useSimilarFetch = (elementType, elementId) => {
const [similarElements, setSimilarElements] = useState({elements: []})
const [similarLoading, setSimilarLoading] = useState(false)
const [_error, _setError] = useState(false)
const fetchSimilarElements = useCallback(async (endpoint) => {
console.log(">>> fetching similar elements <<<")
setSimilarLoading(true)
try {
await axios.get(endpoint)
.then(response => {
setSimilarElements(() => ({
elements: [...response.data.results],
currentPage: response.data.page,
totalPages: response.data.total_pages
}))
})
} catch (error) {
_setError(true)
} finally {
setSimilarLoading(false)
}
}, [])
useEffect(() => {
fetchSimilarElements(getSimilar(elementType, elementId));
}, [fetchSimilarElements, elementType, elementId])
return [{similarElements, similarLoading, _error}, fetchSimilarElements]
}
Then, in my ShowInfoComponent I call all the needed hooks like this:
const {showId} = useParams()
const [data, loading, _error] = useShowInfoFetch({showId})
const [{similarElements, similarLoading}] = useSimilarFetch("tv", showId)
Thanks.
By the time showId changes, data has to wait one additional render cycle, so showId is already used even though data has not yet been fetched. The UI relies on both showId and data, yet data depends on showId. One way to solve this could be having your UI to rely on data alone. What about the id? Add it to data for example. We merely want to avoid the desynchronization.
Something like this:
export const useShowInfoFetch = ({showId}) => {
const [data, setData] = useState({})
const [loading, setLoading] = useState(false)
const [_error, _setError] = useState(false)
const fetchShowInfo = useCallback(() => {
setLoading(true)
try {
axios.get(getShowInfo(showId))
.then(response => {
setData({ id: showId, info: response.data})
})
} catch (error) {
_setError(true)
} finally {
setLoading(false)
}
}, [showId])
useEffect(() => {
fetchShowInfo()
}, [fetchShowInfo])
return [data, loading, _error]
}
Then use data.id to build your links.
If response.data already contains the id, then even better, use that.
That's just an example, of course but hopefully you get the idea.
I might be wrong but I believe you are not watching the correct value on the useEffect. You should be watching showId and not the function fetchShowInfo. That is:
useEffect(() => {
fetchShowInfo()
}, [showId]) --> HERE
And as you are memoized the callback, if you are watching the wrong variable then you will get back the 'last answered'.
We have a ReactJs application which used Firebase. When you first register for the application and you log in for the first time, the app loads a document from Firebase using the onSnapshot method, and renders a component that uses the data in the view. The problem is, when we make changes to the loaded document and those changes are written back to Firebase, the ReactJs application isn't picking up that those changes have been applied and so the view isn't updated. If however, we refresh the app, the changes we've made are rendered and future changes are picked up as normal and everything is fine.
Here is the code where we are calling the onSnapshot method. You can see I've stuck some debugging text in there, this is only rendered once when the document is not loaded, so I know that the problem is that this isn't picking up the document changes in firestore.
function useHub(hubId) {
console.debug("useHub");
const Firebase = React.useContext(FirebaseContext);
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(false);
const [hub, setHub] = React.useState(null);
React.useEffect(() => {
console.debug("useHub: useEffect");
setHub(null);
console.log('****************************');
console.log("Hub ID " + hubId);
if (hubId) {
const unsubscribe = Firebase.firestore()
.collection("hubs")
.doc(hubId)
.onSnapshot(
(doc) => {
const hubDoc = Object.assign({}, { id: doc.id }, doc.data());
console.log('***************************');
console.log('***************************');
console.log(hubDoc);
console.log('***************************');
console.log('***************************');
setHub(hubDoc);
setLoading(false);
setError(false);
},
(error) => {
console.error("Error:", error);
setError(error.message);
setLoading(false);
}
);
return () => unsubscribe();
}
}, [Firebase, hubId]);
return {
loading,
error,
hub,
};
}
export { useHub };
What are the possible reasons why this would be occuring?
You may consider to have your component update itself as a workaround. I have found this document here, which describes the details.
I am trying to fetch the api data and put it inside the tables, now i am using mock data
so I was able to write successfully actions and reducers.
now I am able to call the api.
but in the network call I am not see response in the api and seeing blocked response content status.
I am using react hooks for react and redux.
this is where I am making the api call
useEffect(() => {
getPosts(channel);
}, []);
can you tell me how to fix it.
providing my code snippet and sandbox below.
https://codesandbox.io/s/material-demo-kpt5i
demo.js
const channel = useSelector(state => state.channel);
const dispatch = useDispatch();
const getPosts = channel => dispatch(fetchPosts(channel));
useEffect(() => {
getPosts(channel);
}, []);
actions.js
export function fetchPosts(channel) {
return function(dispatch) {
dispatch(requestPosts());
return fetch(`http://jsonplaceholder.typicode.com/users`)
.then(
response => response.json(),
error => console.log("An error occurred.", error)
)
.then(json => {
dispatch(receivedPosts(json));
});
};
}
according to your sample on codesandbox, it is due to you are loading from https site but your source is from http. change http://jsonplaceholder.typicode.com/users to https://jsonplaceholder.typicode.com/users will solve your issue.