I am trying to display a list of towns or departments from an API, I can display the data with console.log but when i put it in html its not working.
here's my ListTown.js:
import React, { useEffect, useState } from "react";
import api from "./api";
function ListTowns() {
const DEPARTEMENTS = "/get/location/departements";
const [departements, setDepartements] = useState([]);
useEffect(() => {
const fetchData = async () => {
const response = await api.get(DEPARTEMENTS).then((response) => {
setDepartements(response.data.data.departements);
});
};
fetchData();
}, []);
return (
<div>
<ul>
{departements.map((dep) => {
<li key={dep.id}>{dep.name}</li>;
})}
</ul>
</div>
);
}
export default ListTowns;
console log (dep.name) gives this result console.log(dep.name)
You forgot to return the data out of your .map method, so right now it's returning undefined for each element.
{departements.map((dep) => {
return <li key={dep.id}>{dep.name}</li>;
})}
Related
I'm facing difficulty displaying data in React - Here is my code:
import Axios from 'axios';
import { useNavigate } from 'react-router';
export default function ProductCatalog() {
let navigate = useNavigate();
function addProduct() {
navigate('/adding')
}
const [products, setProducts] = useState([{}])
useEffect(() => {
const axiosProd = async () => {
const response = await Axios('http://localhost:3001/getProducts');
setProducts(response.data)
};
axiosProd();
}, []);
const useProducts = products.map((product)=>{
return <div>
<h1>{product.name}</h1>
</div>
})
return(
<>
<button className = "button" onClick={addProduct}>Add New Product</button>
<br></br>
{useProducts}
</>
)
}
I know data is coming in as JSON Objects as when i follow the link of http://localhost:3001/getProducts, I see my data. What am i doing wrong?
You should make a function then outside of the function call the use effect.
To do a get request using axios use axios.get(api)
For example:
// Get All Shoes
const getShoes = () => {
axios.get('/shoes')
.then(res => setShoes(res.data))
.catch(err => console.log(err));
}
Then
useEffect(() => {
getShoes();
}, [])
I'm trying to display a piece of data from an API, I can reach it, but its giving me an unknown error I cant find an answer for it.
The error message :
Uncaught TypeError: Cannot read properties of undefined (reading 'front_default')
now, here's the funny part, when i first starting the page, its working, but if i refresh it, its giving me the error message on console and a white screen page.
this is the part of my code that don't seems to work.
<img src={urlData.sprites.front_default}></img>
but, similar data can work, such as this line:
<p> {urlData.id}</p>
I'll post the all code under here, but don't waste your time on reading it all, try focus on the error message and error origin in order of helping me identifying the problem.
dad component:
import './App.css';
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { PokemonContainer } from './components/Pokemon';
function App() {
const [pokemonData, setPokemonData] = useState([]);
const [loaded, setLoaded] = useState(false);
const get_pokemon_data = async () => {
setPokemonData((await axios.get('https://pokeapi.co/api/v2/pokemon?limit=9')).data.results);
};
useEffect(() => {
get_pokemon_data();
}, []);
useEffect(() => {
setLoaded(true);
}, [pokemonData]);
if (loaded) {
return (
<div>
{pokemonData.map((pokemon: any) => (
<PokemonContainer key={pokemon.name} url={pokemon.url} />
))}
</div>
);
} else {
return (
<div>
<p>wait a minute</p>
</div>
)
}
};
export default App;
child component :
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export const PokemonContainer = (props: any) => {
const [urlData, setURLData] = useState<any>([]);
const [loaded, setLoaded] = useState<boolean>(false);
useEffect(() => {
const get_url_data = async () => {
setURLData((await axios.get(props.url)).data);
};
get_url_data();
}, []);
useEffect(() => {
setLoaded(true);
}, [urlData]);
if (loaded) {
return (
<div>
<div key={urlData.name}>
<p> {urlData.name}</p>
<p> {urlData.id}</p>
<img src={urlData.sprites.front_default}></img>
</div>
</div>
)
} else {
return (
<div>
<p>Loading...</p>
</div>
)
}
};
I think the problem is with your second useEffect
useEffect(() => {
setLoaded(true);
}, [urlData]);
When component mounts this will set loaded to true but response is not fetched yet and urlData is still an empty array (which should be an empty object, I believe) therefore you get the error.
One way to fix this would be to check if urlData has been fetched inside the useEffect? if yes, then set loaded to true.
But I think this useEffecte is not needed at all. Instead of if(loaded) you could check for one urlData's properties, like: if(urlData.id)
child component:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export const PokemonContainer = (props: any) => {
const [urlData, setURLData] = useState<any>([]);
useEffect(() => {
const get_url_data = async () => {
setURLData((await axios.get(props.url)).data);
};
get_url_data();
}, []);
if (urlData.id) {
return (
<div>
<div key={urlData.name}>
<p> {urlData.name}</p>
<p> {urlData.id}</p>
<img src={urlData.sprites.front_default}></img>
</div>
</div>
)
} else {
return (
<div>
<p>Loading...</p>
</div>
)
}
};
Or you can do it like:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export const PokemonContainer = (props: any) => {
const [urlData, setURLData] = useState<any>([]);
useEffect(() => {
const get_url_data = async () => {
setURLData((await axios.get(props.url)).data);
};
get_url_data();
}, []);
if (!urlData.id) {
return (
<div>
<p>Loading...</p>
</div>
);
}
return (
<div>
<div key={urlData.name}>
<p> {urlData.name}</p>
<p> {urlData.id}</p>
<img src={urlData.sprites.front_default}></img>
</div>
</div>
);
};
I am currently trying to setup a React web app using React hooks. I try to pull the items from the JSON with Map but I receive this error.
TypeError: items is undefined
Shop.js
import React, {useState, useEffect} from 'react';
import './App.css';
function Shop() {
useEffect(() => {
fetchItems();
}, []);
const [items, setItems] = useState([]);
const fetchItems = async () => {
const data = await fetch('https://fortnite-api.theapinetwork.com/upcoming/get');
const items = await data.json();
console.log(items.items);
setItems(items.items);
};
return (
<div>
{items.map(item => (
<h1>{item.map}</h1>
))}
</div>
);
}
export default Shop;
I'm not an expert on React, but I'm pretty sure its because you get to the return statement before you define items.
That function is async, so while it takes its turn running each line, the program itself will move on, thus getting to the return with "items" in it before items is actually defined.
What might fix it is doing an if/else that checks if items is defined, then returns either blank html or the html with items. React dynamically updates so that should then return the correct html once items is loaded.
This should solve your question. I have checked the response from the GET request you provided and you have used the incorrect data structuring when pulling fields out. Try the code below.
import React, {useState, useEffect} from 'react';
import './App.css';
function Shop() {
useEffect(() => {
fetchItems();
}, []);
const [items, setItems] = useState([]);
const fetchItems = async () => {
const response = await fetch('https://fortnite-api.theapinetwork.com/upcoming/get');
const deserialisedResponse = await response.json();
setItems(deserialisedResponse.data);
};
return (
<div>
{items.map((item, index) => (
<h1 key={index}>{item.map}</h1>
))}
</div>
);
}
export default Shop;
I've tried on my end and confirmed it works.
Let me show the codes.
function Shop() {
useEffect(() => {
fetchItems();
}, []);
const [items, setItems] = useState([]);
const fetchItems = async () => {
const response = await fetch('https://fortnite-api.theapinetwork.com/upcoming/get');
const deserialisedResponse = await response.json();
console.log("result: ", deserialisedResponse)
setItems(deserialisedResponse.data);
};
return (
<div>
{items.map((item, idx) => (
<h1 key={idx}>{item.item.name}</h1>
))}
</div>
)
}
Please have a check and let me know if it works or not.
I'm new to react, I'm getting this error constantly and after google some I can't find the reason why the useState value can't be read as array :( ... this the error I'm getting: 'TypeError: team.map is not a function'
import React, { useEffect, useState } from "react";
const SportTeams = () => {
const [team, setTeam] = useState([]);
useEffect(() => {
const getSports = async () => {
const response = await fetch("https://www.thesportsdb.com/api/v1/json/1/all_sports.php");
const data = await response.json();
setTeam(data);
console.log(data);
}
getSports();
}, []);
return (
<div className="myClass">
<ul>
{team.map((sport, index) => {
return <li key={`${sport.strSport}-${index}`}>{sport.strSport}</li>
})}
</ul>
</div>
);
};
export default SportTeams;
Just update setTeam like following, your error will be resolved.
setTeam(data.sports);
It is because you are setting the team state with the data without checking if its undefined. If the data is undefined your state team become undefined as well. So make sure to check the data.
import React, { useEffect, useState } from "react";
const SportTeams = () => {
const [team, setTeam] = useState([]);
useEffect(() => {
const getSports = async () => {
const response = await fetch("https://www.thesportsdb.com/api/v1/json/1/all_sports.php");
if (response) {
const data = await response.json();
if (data) {
setTeam(data);
}
}
console.log(data);
}
getSports();
}, []);
return (
<div className="myClass">
<ul>
{team.map((sport, index) => {
return <li key={`${sport.strSport}-${index}`}>{sport.strSport}</li>
})}
</ul>
</div>
);
};
export default SportTeams;
There might also be the chance that your response is not what you expected and the actual data might be inside your response. In that case you need check what your response first then proceed to set the data.
As I said in my comment. the value you are setting to teams isn't an array.
const data = await response.json();
setTeam(data.sports);
What I am doing is to load data from my local storage which I have fetched from https://jsonplaceholder.typicode.com/users. I am trying to create a react application in which I have added multiple users as a friend just like facebook. my friend list is in the file called UserInfo.js which code I have given bellow. then I tried to show friends corresponding to their id by comparing with the id which I tried to find from api call so that this can show me the matching users.
You can find my project here: https://codesandbox.io/s/elastic-dream-mp3is?file=/src/App.js
import React, { useState } from "react";
import "./UserInfo.css";
import { useEffect } from "react";
import fakedata from "../../fakedata";
import { getDatabaseCart } from "../../utilities/databaseManager";
const UserInfo = () => {
// // using fakedata
// const [users, setUsers] = useState(fakedata);
// // declaring state while calling api
const [users, setUsers] = useState([]);
// declaring state while loading data from local storage
const [friends, setFriends] = useState(users);
// to load data from Api call
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((data) => setUsers(data));
}, []);
// to load data from local storage
useEffect(() => {
const savedFriends = getDatabaseCart();
const friendsId = Object.keys(savedFriends);
const countFriends = friendsId.map((key) => {
const friend = friends.find((fd) => fd.id == key);
// console.log(friend);
return friend;
});
setFriends(countFriends);
}, [friends]);
// console.log(friends);
// console.log(users);
return (
<div className="userInfo-container">
<div className="userInfo">
{friends.map((friend) => (
<div>
<h4>Name: {friend.name}</h4>
</div>
))}
</div>
</div>
);
};
export default UserInfo;
I have created fakedata collecting data from jsonplaceholder and tested according to above method and it worked perfectly. but when I tried to load data API call, I got the following error:
the first error indicates that it can not read property of name which I tried to return from local Storage after matching the id with api call.
2.second error denotes which I can't understand in my case. I have tried abortCall to handle this error. the error gone but my problem still exits. what can I do now????
With hooks:
import React, { useState } from "react";
//import "./UserInfo.css";
import { useEffect } from "react";
import fakedata from "../../fakedata";
import { getDatabaseCart } from "../../utilities/databaseManager";
const UserInfo = () => {
// // using fakedata
// const [users, setUsers] = useState(fakedata);
// // declaring state while calling api
const [users, setUsers] = useState([]);
// declaring state while loading data from local storage
const [friends, setFriends] = useState([]);
// to load data from Api call
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((data) => setUsers(data));
}, []);
// to load data from local storage
useEffect(() => {
const savedFriends = getDatabaseCart();
const friendsId = Object.keys(savedFriends);
setFriends(friendsId);
}, []);
// console.log(friends);
// console.log(users);
return (
<div className="userInfo-container">
<div className="userInfo">
{users.length > 0 && friends.map((friendId) => {
const friend = users.find(user => user.id === parseInt(friendId));
return (
<div>
<h4>Name: {friend && friend.name}</h4>
</div>
)})}
</div>
</div>
);
};
export default UserInfo;
In the render, Friends return [{0:undefined}]. You are not setting friends correctly.
I make a Class version of your UserInfo component. It works like this.
import React from "react";
import { getDatabaseCart } from "../../utilities/databaseManager";
class UserInfo extends React.Component {
state = {
users: [],
friends: []
}
componentDidMount = () => {
this.getDataFromServer();
this.getDateFromLocalStorage();
}
getDataFromServer = () => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((data) => this.setState({users:data}));
}
getDateFromLocalStorage = () => {
const savedFriends = getDatabaseCart();
const friendsId = Object.keys(savedFriends);
//console.log(friendsId)
this.setState({friends:friendsId})
}
render() {
const {users, friends} = this.state;
// console.log('users',users, friends);
// console.log('friends', friends);
return (
<div className="userInfo-container">
<div className="userInfo">
{users.length > 0 && friends.map((friendId) => {
const friend = users.find(user => user.id === parseInt(friendId));
return (
<div>
<h4>Name: {friend && friend.name}</h4>
</div>
)})}
</div>
</div>
);
}
}
export default UserInfo;
Note you have a promise for the 'fetch' so at first render and until users are fetched user = [] empty array. To avoid errors it's good to check the length of users before try to map friends.
You can remove the friend check here because if friends array is empty, there is nothing to map.
return (
<div>
<h4>Name: {friend.name}</h4>
</div>
)
Now, it should be a list with ul and li.