I'm using react and trying to fetch data from this API
https://6033c4d8843b15001793194e.mockapi.io/api/locations
I want to get the name, but it is not loading anything. How do i debug that and see what part of my code is working and what isn't?
function Card() {
const url = "https://6033c4d8843b15001793194e.mockapi.io/api/locations";
const [locations, setLocations] = useState(null);
useEffect(() => {
axios.get(url)
.then(response => {
setLocations(response.data)
})
}, [url])
if(locations) {
return (
<div>
<h1>Acme HQ</h1>
<p>{locations.id}</p>
</div>
)
}
return (
<div>
<h1>error</h1>
</div>
)
}
This is my code, it doesn't throw any error but it also doesn't output anything.
I want to retrieve the name or the usercount from that API
Because the api return an array of object. So you can get an id of item in the array like this:
{locations?.[0].id}
To render items from array. You can using map: https://reactjs.org/docs/lists-and-keys.html
Related
I am rendering a product list from dummyjson
getting response from api
but showing products.map() is not a function
const fetchData = async () => {
const response = await fetch("https://dummyjson.com/products");
const data = await response.json();
return setProducts(data);
}
useEffect(() => {
fetchData();
},[])
console.log(products)
return (
<div>
<ul>
{products.map((product, index) => {
return (
<li key={index}>
<h2>{product.title}</h2>
</li>
);
})}
</ul>
</div>
)
The api returns an object with a property products which contains the products array, so you need to do
{products.products.map((product, index) => {
Alternatively, you could store just the products array in state like so, and you can keep your existing map code.
return setProducts(data.products);
Your data is an object. What you want to do is extract products from the JSON response, so in fetchData method you should call: setProducts(data.products).
I'm trying to map an array of movies which I get from an API.
The data is fetched successfully but when I try to map the values and display, it becomes undefined and does not show anything.
I'm new to React so any help and advice would be helpful.
const [items, setItems] = useState([]);
const getMovieData = () => {
axios
.get(api_url)
.then((response) => {
const allMovies = response.data;
console.log(allMovies);
setItems(allMovies);
})
.catch((error) => console.error(`Error: ${error}`));
};
useEffect(() => {
getMovieData();
}, []);
return (
<div>
{items.map((item) => {
<p>{item.title}</p>;
})}
</div>
);
The data is stored like this:
0: {
adult: false,
backdrop_path: '/9eAn20y26wtB3aet7w9lHjuSgZ3.jpg',
id: 507086,
title: 'Jurassic World Dominion',
original_language: 'en',
...
}
You're not returning anything from your map
{
items.map((item) => {
// Add a return
return <p>{item.title}</p>
})
}
First, your items value is an empty array[] as you have initialized with setState([]) and your useEffect() runs only after your component is rendered which means even before you could do your data fetching, your HTML is being displayed inside which you are trying to get {item.title} where your items is an empty array currently and hence undefined. You will face this issue often as you learn along. So if you want to populate paragraph tag with item.title you should fast check if your items is an empty array or not and only after that you can do the mapping as follow and also you need to return the element from the map callback. If it takes some time to fetch the data, you can choose to display a loading indicator as well.
const [items, setItems] = useState([]);
const getMovieData = () => {
axios.get(api_url)
.then((response) => {
const allMovies = response.data;
console.log(allMovies);
setItems(allMovies);
}).catch(error => console.error(`Error: ${error}`));
};
useEffect(() => {
getMovieData();
}, []);
return ( < div > {
items.length !== 0 ? items.map((item) => {
return <p > {
item.title
} < /p>
}) : < LoadingComponent / >
}
<
/div>
);
Good catch by Ryan Zeelie, I did not see it.
Another thing, since you're using promises and waiting for data to retrieve, a good practice is to check if data is present before mapping.
Something like :
return (
<div>
{ (items.length === 0) ? <p>Loading...</p> : items.map( (item)=>{
<p>{item.title}</p>
})}
</div>
);
Basically, if the array is empty (data is not retrieved or data is empty), display a loading instead of mapping the empty array.
I'm trying to load data using React and Firebase.
Unfortunately, I can't get it to display them.
In Firebase's res.items.forEach((itemRef) function, I fill an array.
I would like to access this later. However, this is then empty. How so ?
const array = [];
function loadList() {
const storage = getStorage();
const storageRef = sRef(storage, "images/");
// Find all the prefixes and items.
listAll(storageRef)
.then((res) => {
res.prefixes.forEach((folderRef) => {
// All the prefixes under listRef.
// You may call listAll() recursively on them.
});
res.items.forEach((itemRef) => {
array.push(itemRef._location);
// All the items under listRef.
console.log(itemRef._location);
});
})
.catch((error) => {
// Uh-oh, an error occurred!
});
}
function App() {
loadList();
return (
<div className="App">
<Stack direction="row" alignItems="center" spacing={2}>
// ARRAY IS EMPTY
{array?.map((value, key) => {
return <h1>{value}</h1>;
})}
...
From your explaination, here is what I gathered you are trying to do:
Fetch the documents from cloud firestore.
Store them in an array.
Create a list of Components in the browser view rendered by react using the array that was fetched.
For such, fetching and rendering tasks, your best bet would be using Callbacks, State and Effect.
So:
State would hold the values for react to render.
Effect will fetch the data when the component loads.
Callback will do the actual fetching because asynchronous fetching on useEffect directly is discouraged.
const storage = getStorage();
const listRef = ref(storage, 'files/uid');
function ImageApp()
{
// This is the array state of items that react will eventually render
// It is set to empty initially because we will have to fetch the data
const [items, setItems] = React.useState([]);
React.useEffect(() =>
{
fetchItemsFromFirebase();
}, []); // <- Empty array means this will only run when ImageApp is intially rendered, similar to onComponentMount for class
const fetchItemsFromFirebase = React.useCallback(async () =>
{
await listAll(listRef)
.then((res) =>
{
// If (res.items) is already an array, then use the method below, it would be faster than iterating over every single location
// cosnt values = res.items.map((item) => item._location);
// If res.items doesnt already return an array, then you unfortunately have to add each item individually
const values = [];
for (const itemRef of res.items)
{
values.push(itemRef._location);
}
console.log(values);
setItems(values);
})
.catch((error) => { console.error(error) });
}, []); // <- add "useState" values inside the array if you want the fetch to happen every smth it changes
return (
<div className="App">
{
items && // Makes sure the fragment below will only be rendered if `items` is not undefined
// An empty array is not undefined so this will always return false, but its good to use for the future :)
<>
{
(items.map((item, itemIndex) =>
<h1 key={ itemIndex }>{ item }</h1>
))
}
</>
}
</div>
)
}
Having an issue with a piece of my code. I fetch from flask server, and display with div in React. I want to select the div and have that information pass to a new object array to return back to flask, but I keep getting undefined.
Code snippet:
function PLCPage() {
const [myjunk, setMyjunk] = useState([]);
const [devList, setDevList] = useState ([]);
const Scan = () => {
fetch('/api/home').then(response => {
if(response.status === 200){
return response.json()
}
})
.then(data => setMyjunk(data))
.then(error => console.log(error))
}
const Clear = () => {
setMyjunk({})
}
Creating the divs:
{Object.keys(myjunk).map((key) =>{
return (
<div className='plc-container' key={key} onClick={ReadStuff}>
<h1>ID:{myjunk[key]['name']}</h1>
<h1>IP:{myjunk[key]['IP']}</h1>
</div>
)
Clicking on the div, just to return a console log returns undefined.
const ReadStuff = () => {
console.log(this.IP)
}
I eventually want to return the data I have in the 2 h1 tags to a new object (devList) but I can't even get it to console log. Sorry if this is basic but I've been stumped at this for a week. Thanks
I've tried this.IP, myjunk.IP, this,myjunk.IP. myjunk['IP']. Nothing returns. And when I do myjunk.IP I get "cant read from undefined"
One way to do this is to create a separate component:
const JunkButton = ({junk}) => (
<div className='plc-container' key={key} onClick={() => ReadStuff(junk)}>
<h1>ID:{junk['name']}</h1>
<h1>IP:{junk['IP']}</h1>
</div>
)
Now your map() looks like:
{Object.keys(myjunk).map((key) =>{ <JunkButton junk={ myjunk[key] }/> }
And ReadStuff becomes:
const ReadStuff = (junk) => { console.log(junk) }
Notice how in React we explicitly pass things around as props or function parameters.
first you need to pass myjuck to function and then console it like this:
{Object.keys(myjunk).map((key) =>{
return (
// sending myjuck to function whatever that is
<div className='plc-container' key={key} onClick={() => ReadStuff(myjunk)}>
<h1>ID:{myjunk[key]['name']}</h1>
<h1>IP:{myjunk[key]['IP']}</h1>
</div>
)
ReadStuff function
const ReadStuff = (myjunk) => { console.log(tmyjunk) }
I am new to react and firebase/firestore.
I am trying to map into what I believe to be a nested firestore value. I am able to pull each value individually
function Pull() {
const [blogs,setBlogs]=useState([])
const fetchBlogs=async()=>{
const response=firestore.collection('customer');
const data= await response.get();
data.docs.forEach(item=>{
setBlogs(data.docs.map(d => d.data()))
console.log(data)
})
}
useEffect(() => {
fetchBlogs();
}, [])
return (
<div className="App">
{
blogs.map((items)=>(
<div>
<p>{items[1].name}</p>
</div>
))
}
</div>
);
}
I have been trying to map twice to get into the string inside the collection, yet I have had no luck.
My FireStore collection
https://drive.google.com/file/d/1Erfi2CVrBSbWocQXGR5PB_ozgg9KEu12/view?usp=sharing
Thank you for your time!
If you are iterating a data.docs array and enqueueing multiple state updates then you will want to use a functional state update to correctly enqueue, and update from the previous state.
const fetchBlogs = async ( )=> {
const response = firestore.collection('customer');
const data = await response.get();
data.docs.forEach(item => {
setBlogs(blogs => blogs.concat(item.data()))
});
}
or you can map the data.docs to an array of items and update state once.
const fetchBlogs = async ( )=> {
const response = firestore.collection('customer');
const data = await response.get();
setBlogs(blogs => blogs.concat(data.docs.map(item => item.data())));
}
try changing the foreach to a snapshot like this:
data.docs.onSnapshot(snapshot=>{
setBlogs(snapshot.docs.map(d => d.data()))
console.log(data)
})
ive used it like this in the past multiple times
and it has worked. If it doesnt work, the instagram clone tutorial on youtube by Clever Programmer goes over this well.