i think this is to basic question, but this is problem i have right now and i cannot find solution.
I am trying to show data from API i created on postman
React.js code is here
const urlCategories = '127.0.0.1:8000/api/categories';
const [service, setService] = useState([]);
const fetchCategories = async () => {
const response = await fetch(urlCategories);
const service = await response.json();
console.log(service);
};
useEffect(() => {
fetchCategories();
}, []);
error in console
Uncaught (in promise) SyntaxError: JSON.parse: unexpected character at
line 1 column 1 of the JSON data
http missing
const urlCategories = 'https://127.0.0.1:8000/api/categories';
const [service, setService] = useState([]);
const fetchCategories = async () => {
const response = await fetch(urlCategories);
const service = await response.json();
console.log(service);
};
useEffect(() => {
fetchCategories();
}, []);
Related
I am also using getStaticprops from next.js.
I am trying to fetch data , I am following the code on firebase documentation, but i keep running into a error
export const getStaticProps = async () => {
const res = await fetch(
"https://jsonplaceholder.typicode.com/photos?_limit=4"
);
const images = await res.json();
console.log(auth.currentUser);
//
const userRef = ref(database, "users/" + auth.currentUser.uid);
onValue(userRef, (snapshot) => {
const properties = snapshot.val();
console.log(properties);
});
//
return {
props: {
images,
properties,
},
};
};
I have a problem with one of my components. The problem I think I have is that my component executes before my user context stores the currentUser. My code only works when doing a hot reload.
The watchlist component gets all the values from the watchlist array where the document matches the currentUser.uid.
UserContext.js:
const [currentUser, setCurrentUser] = useState(null)
const [watchlist, setWatchlist] = useState(null)
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user)
})
return unsubscribe
}, [])
const getWatchlist = async () => {
const userRef = await getDoc(doc(db, 'users', currentUser.uid))
setWatchlist(userRef.data().watchlist)
console.log(userRef.data().watchlist)
}
These values are the ids of objects I then GET from an API, these are then pushed to the watchlistData array.
CryptoContext.js
export const getWatchlistData = async (list) => {
const watchlistData = []
for (const item of list) {
const result = await axios.get(
`${coingecko}/coins/${item}`
)
watchlistData.push(result.data)
}
return watchlistData
}
And this is how my Watchlist component code currently looks.
WatchlistItems.jsx
const { watchlist, getWatchlist, currentUser } = useContext(UserContext)
const { dispatch } = useContext(CryptoContext)
useEffect(() => {
if (currentUser) {
dispatch({type: 'SET_LOADING'})
const getWatchlistDataFromAPI = async () => {
await getWatchlist()
const watchlistData = await getWatchlistData(watchlist)
dispatch({type: 'GET_WATCHLIST', payload: watchlistData})
console.log(watchlistData)
}
getWatchlistDataFromAPI()
}
}, [currentUser])
If I refresh the page I get "Uncaught (in promise) TypeError: the list is not iterable", but if I do a hot reload, watchlist, and watchlistData both console.log with the correct data.
This is my first post and so please let me know if I've left anything out.
Thank you in advance for any help :)
I am using fetch to get data from API. I am using useEffect for page to stop rerender. But its not working
const [load, setLoad] = useState(false);
if (load) {
return <h2>Progress</h2>;
}
const fetchPicth = async () => {
setLoad(true);
const response = await fetch(url);
const data = await response.json();
setPicth(data.pink);
};
useEffect(() => {
setLoad(false);
}, [fetchPicth]);
This can be solved using 2 approaches
Pass state in dependency array of useEffect
const [picth, setPicth] = useState([]); // Initial state
useEffect(() => {
if (picth && picth.length !== 0) { // Checks if data exists and length
//is greater than 0
setLoad(false); // Set Loading to false
}
}, [picth]);
const fetchPicth = async () => {
setLoad(true);
const response = await fetch(url);
const data = await response.json();
setPicth(data.pink);
};
Check for the length, display Progress if there is no data. Display if data is present.
{picth.length === 0 && <div>Progress</div>}
{picth.length > 0 && (
<div>
{picth.map((book, index) => {
return (
<YourComponent></YourComponent>
);
})}
Remove the fetchPicth from the dependency array. If you'd like to set load to false you can do it like this:
const [load, setLoad] = useState(false);
if (load) {
return <h2>Progress</h2>;
}
const fetchPicth = async () => {
setLoad(true);
const response = await fetch(url);
const data = await response.json();
setPicth(data.pink);
setLoad(false)
};
useEffect(() => {
fetchPicth();
}, []);
Using the code above will only fetch the data from the API only once i.e; when the component is mounted.
I am doing a React.js project. I am trying to pull data from an API that has multiple endpoints. I am having issues with creating a function that pulls all the data at once without having to do every endpoint separetly. The console.log gives an empty array and nothing gets display. The props 'films' is data from the parent and works fine. It is also from another enpoint of the same API. This is the code:
import { useEffect, useState } from "react";
import styles from './MovieDetail.module.css';
const MovieDetail = ({films}) => {
const [results, setResults] = useState([]);
const fetchApis = async () => {
const peopleApiCall = await fetch('https://www.swapi.tech/api/people/');
const planetsApiCall = await fetch('https://www.swapi.tech/api/planets/');
const starshipsApiCall = await fetch('https://www.swapi.tech/api/starships/');
const vehicleApiCall = await fetch('https://www.swapi.tech/api/vehicles/');
const speciesApiCall = await fetch('https://www.swapi.tech/api/species/');
const json = await [peopleApiCall, planetsApiCall, starshipsApiCall, vehicleApiCall, speciesApiCall].json();
setResults(json.results)
}
useEffect(() => {
fetchApis();
}, [])
console.log('results of fetchApis', results)
return (
<div className={styles.card}>
<div className={styles.container}>
<h1>{films.properties.title}</h1>
<h2>{results.people.name}</h2>
<p>{results.planets.name}</p>
</div>
</div>
);
}
export default MovieDetail;
UPDATE
I just added the post of Phil to the code and I uploaded to a codesanbox
You want to fetch and then retrieve the JSON stream from each request.
Something like this
const urls = {
people: "https://www.swapi.tech/api/people/",
planets: "https://www.swapi.tech/api/planets/",
starships: "https://www.swapi.tech/api/starships/",
vehicles: "https://www.swapi.tech/api/vehicles/",
species: "https://www.swapi.tech/api/species/"
}
// ...
const [results, setResults] = useState({});
const fetchApis = async () => {
try {
const responses = await Promise.all(Object.entries(urls).map(async ([ key, url ]) => {
const res = await fetch(url)
return [ key, (await res.json()).results ]
}))
return Object.fromEntries(responses)
} catch (err) {
console.error(err)
}
}
useEffect(() => {
fetchApis().then(setResults)
}, [])
Each URL will resolve to an array like...
[ "people", [{ uid: ... }] ]
Once all these resolve, they will become an object (via Object.fromEntries()) like
{
people: [{uid: ... }],
planets: [ ... ],
// ...
}
Take note that each property is an array so you'd need something like
<h2>{results.people[0].name}</h2>
or a loop.
Each object should have around 250 arrays in it, but for some reason, each of the objects has a single array except for the last one, which has 1250.
How can I spread out the responses so I can access each one individually?
const [coinData, setCoinData] = useState();
const [loading, setLoading] = useState(true);
useEffect(() => {
createLocalStorage();
let existingLocalStorage = JSON.parse(localStorage.getItem('items'));
const fetchData = async () => {
const data = await Promise.all(
existingLocalStorage.map(obj =>
coinGecko.get(`/coins/${obj[0].coin}/market_chart/`, {
params: {
vs_currency: 'usd',
days: obj[0].time
}
}),
)
);
setCoinData(data);
setLoading(false);
};
fetchData();
}, []);
Here's the response:
response
I'm using create-react-app, and testing with console.log in the browser
I was sending the times as strings ('day', 'week', 'month', 'year', 'max') I totally forgot I needed to convert them to number values. Since max was the only acceptable parameter, that's the only one that returned the response I was looking for
Try calling your method like below-
import axios from 'axios';
useEffect(() => {
createLocalStorage();
let existingLocalStorage = JSON.parse(localStorage.getItem('charts'));
const fetchData = async () => {
await axios.all([api1, api2]).then(axios.spread((...responses) => {
const resp1 = responses[0]
const resp2 = responses[1]
// use the results
})).catch(errors => {
// errors.
})
}
fetchData();
}, []);