I trying make an axios get from context file into function and call this from component to return data.
Context file:
const getPets = async () => {
await axios.get('http://localhost:1337/api/pets?populate=*')
.then((res) => {
return res.data
})
.catch(err => {
console.log(err)
})}
Component file:
const [pets, setPets] = useState([])
useEffect( () => {
setPets(getPets())},[])
return (console.log(pets))
The return value is undefined and i don't know why.
Can we help me please?
Tks!
Modify getPets():
const getPets = async () => {
const res = await axios.get('http://localhost:1337/api/pets? populate=*');
return res.data;
}
getPets() returns a promise
useEffect(() => {
getPets().then(res => setPets(res));
}, []);
return (
<>
{pets?.map(pet => { /* some JSX */})}
</>
);
Related
The below function gets the current location of a user:
const getCurrentLocation = () => {
fetch("https://ipinfo.io/json?token=$TOKEN")
.then((response) => response.json())
.then((jsonResponse) => {
console.log(jsonResponse)
return jsonResponse;
});
};
useEffect(() => {
console.log(getCurrentLocation());
}, []);
logging in useEffect is showing undefined and it is appearing first in the console, then jsonResponse shows next in the console with the corresponding object. Why is that ?
getCurrentLocation doesn't return anything, that's why you got undefined.
Moreover, fetch returns a Promise, which is asynchronous, meaning you don't get the result immediately, you must pass a calback to then to get the result when it is available.
const getCurrentLocation = () => {
return fetch("https://ipinfo.io/json?token=$TOKEN")
.then(response => response.json());
};
useEffect(() => {
getCurrentLocation()
.then(location => console.log(location));
}, []);
The getCurrentLocation function is not returning anything. Try saving the location in the state, so that you can access it when needed:
const [currentLocation, setCurrentLocation] = useState(null);
const getCurrentLocation = () => {
fetch("https://ipinfo.io/json?token=$TOKEN")
.then((response) => response.json())
.then((jsonResponse) => {
setCurrentLocation(jsonResponse); // <- save the location in state
});
};
useEffect(() => {
getCurrentLocation();
}, []);
return <div>{currentLocation}</div>
If you need the location in a useEffect, you could do:
useEffect(() => {
if (currentLocation !== null) {
// ...
}
}, [currentLocation])
you can simply use async/await to get response, take a look at this one:
const getCurrentLocation = async () => {
const result = await fetch("https://ipinfo.io/json?token=$TOKEN");
return result.json();
};
const handleGetLocation = async () => {
const result = await getCurrentLocation();
console.log(result);
};
useEffect(() => {
handleGetLocation();
}, []);
I am building a Project with the Pokemon API. Here it is how I am fetching the data:
pokeAPI.js
export const api = {
getPokemonList: async ({ url }) => {
return new Promise((resolve) => {
fetch(url)
.then(res => res.json())
.then(data => {
resolve(data)
})
});
},
getPokemonInfo: async (url) => {
return new Promise((resolve) => {
fetch(url)
.then(res => res.json())
.then(data => {
resolve(data)
})
});
}
};
App.js
const [pokemon, setPokemon] = useState([]);
const URL = 'https://pokeapi.co/api/v2/pokemon?limit=150';
useEffect(() => {
const getPokemonInfo = async () => {
const json = await api.getPokemonInfo(URL);
await loadPokemon(json.results);
};
getPokemonInfo();
}, []);
const loadPokemon = async (data) => {
let pokemonData = await Promise.all(data.map(async pokemon => {
let pokemonList = await api.getPokemonList(pokemon)
return pokemonList
}))
setPokemon(pokemonData);
};
Although this works, it's currently calling getPokemonList for every pokemon and the fact that there are multiple async / await is not helping with readiability. How could I refactor this logic:
const loadPokemon = async (data) => {
let pokemonData = await Promise.all(data.map(async pokemon => {
let pokemonList = await api.getPokemonList(pokemon)
return pokemonList
}))
setPokemon(pokemonData);
};
to fetch only once, using a memoized value in a hook to prevent multiple re-renders?
Thanks for helping.
`there are several ways to do it, you can use redux like state managements or browsers local storage
const App = () => {
const [pokemons, setPokemons] = useState([]);
useEffect(() => {
let pokemons= localStorage.getItem("users");
if (pokemons) {
pokemons = JSON.parse(pokemons);
setPokemons({ pokemons });
} else {
fetch("https://pokeapi.co/api/v2/pokemon?limit=150")
.then(res => res.json())
.then(pokemons => {
setPokemons({ pokemons });
localStorage.setItem("pokemons", JSON.stringify(pokemons));
});
}
}, [])
}
I am trying to pass data into a component, however I am getting an error it is saying recipe.map is not a component. Would love some help.
const App = () => {
const [recipe, setRecipe] = useState([]);
const appId = `af783d30`;
const appKey = ``;
const url = `https://api.edamam.com/search?q=chicken&app_id=${appId}&app_key=${appKey}&from=0&to=3&calories=591-722&health=alcohol-free`;
console.log(url);
useEffect(() => {
const fetchData = async () => {
try {
const res = await axios.get(url);
setRecipe(res.data);
console.log(res.data);
} catch (err) {
console.error(err);
}
};
fetchData();
}, []);
return (
<div>
{recipe.map((r) => {
return <RecipeCard recipe={r} />;
})}
</div>
);
};
export default App;
in useEffect hook i used a function to send request to api for search.
function name is searchCharacters and it is outside of component.
i get error
TypeError: searchCharacters(...) is undefined when my code excuted on that point. why? how can in fix this?
error img:
function Dashboard() {
const [searchParam, setSearchParam] = useState("");
const [results, setResults] = useState([]);
const [isSearching, setIsSearching] = useState(false)
const debouncedSearchTerm = useDebounce(searchParam, 500);
useEffect( ()=> {
if(debouncedSearchTerm){
setIsSearching(true);
searchCharacters(debouncedSearchTerm).then(res => {
setIsSearching(false);
console.log("im search result", res);
setResults(res);
});
}else{
setResults([]);
}
}, [debouncedSearchTerm]);
}
function searchCharacters(search){
api.get(`client/search?q=${search}`).then(
(res) => {
return res.data;
}
).catch( e => {
console.log(e);
return [];
})
}
export default Dashboard;
searchCharacters doesn't return a Promise to chain from. Return the api.get Promise chain from searchCharacters.
function searchCharacters(search) {
return api
.get(`client/search?q=${search}`)
.then((res) => {
return res.data;
})
.catch((e) => {
console.log(e);
return [];
});
}
Or slightly more succinct
const searchCharacters = (search) =>
api
.get(`client/search?q=${search}`)
.then((res) => res.data)
.catch((e) => {
console.log(e);
return [];
});
So basically, I'm trying to fetch data from api and pass it to Component.
I create usePosition hook to get my positon from browser, and then get response from api. I really don't know how to wait with useEffect for my position, when i'm executing this code now I'm getting always log 'no position'.
const usePosition = () => {
const [error, setError] = useState(null);
const [position, setPosition] = useState();
useEffect(() => {
const geo = navigator.geolocation;
if(!geo) {
setError('Geolocation is not supported.');
return;
}
const handleSuccess = position => {
const { latitude, longitude } = position.coords;
setPosition({
latitude,
longitude
});
};
const handleError = error => {
setError(error.message);
};
geo.getCurrentPosition(handleSuccess, handleError);
}, []);
return { position, error };
}
function App() {
const {position, error} = usePositon();
const [weather, setWeather] = useState([]);
useEffect(() => {
if(position) {
const URL = `https://api.openweathermap.org/data/2.5/onecall?lat=${position.latitude}&lon=${position.longitude}&exclude=current,minutely,daily&units=metric&lang=pl&appid=${API_KEY}`;
const fetchData = async () => {
const result = await fetch(URL)
.then(res => res.json())
.then(data => data);
setWeather(result.hourly);
}
fetchData();
} else {
console.log('no position');
}
}, []);
return (
<div className="App">
<div>
<Swiper weather={weather}/>
</div>
</div>
)
}
It's all because of [] empty dependencies list down in App's useEffect. It runs exactly once on mount, when usePosition has not requested anything yet. And once it successes later and returns different { error, position } App does not react.
How to solve? Provide things as dependencies:
useEffect(() => {
if(position) {
const URL = `https://api.openweathermap.org/data/2.5/onecall?lat=${position.latitude}&lon=${position.longitude}&exclude=current,minutely,daily&units=metric&lang=pl&appid=${API_KEY}`;
const fetchData = async () => {
const result = await fetch(URL)
.then(res => res.json())
.then(data => data);
setWeather(result.hourly);
}
fetchData();
} else {
console.log('no position');
}
}, [position, error]);