Im trying to get data out of an API with fetch, i can console.log the result in the fetch but out of the fetch i cant reach the data.
So i got this fetchData.js file with the function in it:
export const fetchData = (url) => {
return fetch(url)
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.log('error', error))
}
and then in the app.jsx file i call the function like this:
import { fetchData } from "./fetchData";
const URL = "https://pokeapi.co/api/v2/pokemon"
function App() {
let data = fetchData(URL);
console.log(data);
//return etc
But the console.log(data) keeps saying "undefined"
Can somebody please help me ?
You have to wait for the asynchronous action to complete before logging it.
let data = fetchData(URL).then(() => {console.log(data);});
(also either remove then(result => console.log(result)) or return result from it)
fetchData is an async function, that is why the console.log is executed before fetchData is resolved:
export const fetchData = async (url) => {
return fetch(url)
.then(response => response.json())
.then(result => (result)) //--> data
.catch(error => console.log('error', error))
}
then in component, inside useEffect:
function App() {
const [data, setData] = useState([]) //--> keep data in component state
useEffect(()=> {
fetchData(URL) //--> fetch data when component is mounted
.then(response => setData(response))
}, []);
//...
}
Related
I am trying to fetch user data using the GitHub API, but when I make a request using fetch() the request is not sent until after the return(). The response data will only show after the page loads, but I need it before render to use as HTML parameters. I know it has something to do with JSON requests being asynchronous, but I'm not sure how to change the code to set the data properly.
const user = params.get("user");
const [userData, setUserData] = useState(null);
const [reqLimit, setReqLimit] = useState(null);
const getUserData = () => {
fetch(`https://api.github.com/users/${user}`)
.then(response => {response.json();})
.then(json => console.log(json))//'undefined'
.then(json => setUserData(json))
.catch(error => {
console.error('Error:', error);
});
};
useMemo(() => {
fetch(`https://api.github.com/rate_limit`)
.then(response => response.json())
.then(json => {
setReqLimit(json.resources.core);
if (json.resources.core.remaining < 1) {
console.error('Error:', 40
}
});
getUserData();
}, [userData]);
return (
<main>
//userData = null; (Why?)
</main>
)
fetch(`https://api.github.com/users/${user}`)
.then(response => response.json();) // return json
//.then(json => console.log(json))//'undefined' remove this from here
.then(json => setUserData(json))
.catch(error => {
console.error('Error:', error);
});
I am using next-redux-wrapper, and i can get data to server store, but i cant send it to client store.
My code looks like this:
In /pages/index:
export const getServerSideProps = wrapper.getServerSideProps(async (ctx) => {
ctx.store.dispatch(testFunc(ctx));
return {props: {data: ctx.store.getState().test.data}}
})
In store/../action:
export const testFunc = (ctx) => (dispatch) => {
return fetch(url)
.then(r => r.json())
.then(r => {
const data = r;
dispatch({type: actionTypes.DATA, data});
})
}
How can i do it right?
I'm struggling with how to fetch data using RxJS and axios onClick in a React component. But getting closer, I think. Any attempts I've tried either run when component mounts, not onClick, or don't run at all even onClick.
Basically, how to call onClick and how to pass a payload. There just seems to be nothing online to explain this which i would expect to be a common situation.
const MyComponent = () => {
const [data, setData] = useState(null);
const getData$ = new Subject(observer => {
axios
.post(`/my-url/`, **how to get payload to here**)
.then(response => {
observer.next(response.data);
observer.complete();
})
.catch(error => {
observer.error(error);
});
});
useEffect(() => {
const subs = getData$.subscribe({
next: res => setData(res),
});
return () => subs.unsubscribe();
}, []);
return (
<Button onClick={() => getData$.next(payload)} />
);
};
Any help appreciated.
you can pass in the payload in getData like this
const getData$ = (payload) => new Subject(observer => {
axios.post(`/my-url/`, payload)
.then(response => {
observer.next(response.data);
observer.complete();
})
.catch(error => {
observer.error(error);
});
});
This basically just creates an anonymous function called getData that returns your Subject. It's equivalent to this:
const getData$ = function (payload) {
return new Subject(observer => {
axios.post(`/my-url/`, payload)
.then(response => {
observer.next(response.data);
observer.complete();
})
.catch(error => {
observer.error(error);
});
});
};
I am new with promise and I can not to solve an issue with promise.
I have to return a new state in function loadPosts after fetching data from API:
[loadPosts]: (state, index) => {
fetchPosts().then( data => {
return {
...state,
postState : {
postList : data.data
}
}
})
}
And this is my fetchPosts function:
export const fetchPosts = () => {
console.log("Fetch posts...");
fetch(process.env.REACT_APP_API_URL + '/post')
.then(response => response.json())
.then(data => {
return data
})
.catch(error => console.error(error))
}
I get "TypeError: Cannot read property 'then' of undefined"
In my understanding, first and second then of fetchPosts function, should return a promise with resolved value but instead I get undefined.
If I change fetch post in this way (adding return):
export const fetchPosts = () => {
console.log("Fetch posts...");
return fetch(process.env.REACT_APP_API_URL + '/post')
.then(response => response.json())
.then(data => {
return data
})
.catch(error => console.error(error))
}
I get another error: reducer "app" returned undefined. To ignore an action, you must explicitly return the previous state.
How can I use promise to reach my goal?
Thanks
First, lets fix your fetchPosts function
export const fetchPosts = () => {
console.log("Fetch posts...");
return fetch(process.env.REACT_APP_API_URL + '/post')
.then(response => response.json())
// the following code is not needed at all
//.then(data => {
// return data
// })
// I prefere not to do the error handling here,
// instead let the caller handle the error
.catch(error => console.error(error))
}
Now that the fetch posts function actually returns something, I can only tell you that there is no way from inside the function in your first code snippet to return a new state with the posts that the fetchPosts promise resolves to.
It looks a lot like a reducer though, so I recommend you take a look at redux-thunk that allows you to enhance redux with a middleware for async behavior and you can then dispatch functions to the store that returns promises.
1.) You need to return the fetch() so that you can chain a .then().
2.) You need to have a default case in your reducer which returns the state.
I have a function that fetches data from the url and is supposed to return it:
const fetchTableData = () => {
fetch('https://api.myjson.com/bins/15psn9')
.then(result => result.json())
.then(data => {
return data;
})
}
export default fetchTableData;
The problem is that when i import this function and try to use it, it always returns undefined.
When i console log the data inside the function itself, you can see it is available. The function just doesn't work when i try to import it.
What is the problem here? Why does it work that way?
Try this =) You have to return something from the fetchTableData function also.
const fetchTableData = () => {
const fetchedData = fetch('https://api.myjson.com/bins/15psn9')
.then(result => result.json())
.then(data => {
return data;
})
return fetchedData;
}
export default fetchTableData;
Or you can just return it like this:
const fetchTableData = () => {
return fetch('https://api.myjson.com/bins/15psn9')
.then(result => result.json())
.then(data => {
return data;
})
}
export default fetchTableData;
In your code you were not returning from the fetchTableData function. Only from the the second then() callback. When a function has no return value, undefined will be returned.
Try this instead:
const fetchTableData = () => {
const myResponse = fetch('https://api.myjson.com/bins/15psn9')
.then(result => result.json())
.then(data => {
return data;
})
return myResponse;
}
export default fetchTableData;
What now happens is the following:
The response return by the second then() function is returning the data.
We are saving this data in a variable, named myResponse.
We are now returning this value from the function fetchTableData.
You need to either store data in a global variable or assign any variable to fetch to get return data.
//First way
fetch('https://api.myjson.com/bins/15psn9')
.then(result => result.json())
.then(data => {
console.log("data",data);
});
//Second way
let binData = null;
fetch('https://api.myjson.com/bins/15psn9')
.then(result => result.json())
.then(data => {
binData = data;
console.log("binData", binData);
});
Here is the working example.