Fetch returns undefined when imported - javascript

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.

Related

How to pass return value from component to another one

I have a const that assembles a get (in another component) and returns me a verification code, this is: response.data.verifyCode
This component is called through a submit on another component.
I need to get this value in my another const, which is below:
export const sendCode = (id, username) => (dispatch) => {
dispatch({ some code here });
return registerAccount
.sendCode(id, username)
.then((response) => {
dispatch({ payload: response.data.verifyCode });
return response.data;
})
.catch(() => {
return null;
});
};
export const getCodeAndVerify = (id, userCode) => (dispatch) => {
dispatch({ some code here });
const getVerifyCode = // I need to get response.data.verifyCode from sendCode above
// I try to use
// const getVerifyCode = { verifyCode: sendCode() };
// but this returns [object object]
return registerAccount
.getCodeAndVerify(id, userCode, getVerifyCode)
.then(() => {
// some code here
})
.catch(() => {
// some code here
});
};
That is, I need to get the verifyCode from the return from the superior const and use it in the other const, but I'm not sure how to do that. Can someone help me?
Asynchronous actions (I'm assuming thunks) also receive a getState second argument after dispatch. Assuming there's a reducer to handle the verifyCode send code success, you can access the store and retrieve the verifyCode value in getCodeAndVerify.
export const sendCode = (id, username) => (dispatch) => {
dispatch({ some code here });
return registerAccount
.sendCode(id, username)
.then((response) => {
dispatch({
type: 'VERIFY_CODE_SUCCESS', // <-- action object needs type
payload: response.data.verifyCode,
});
return response.data;
})
.catch(() => {
return null;
});
};
export const getCodeAndVerify = (id, userCode) => async (dispatch, getState) => {
dispatch({ type: TYPES.PASS_CREATION_REQUESTED });
const getVerifyCode = getState().path.to.verifycode; // <-- retrieve from state
return registerAccount
.getCodeAndVerify(id, userCode, getVerifyCode)
.then(() => {
// some code here
})
.catch(() => {
// some code here
});
};

trying to fetch data with fetch and promise, doesnt work (react)

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))
}, []);
//...
}

Using RxJS and axios, how do you fetch data onClick in React component?

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);
});
});
};

Errror fetching data with promise

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.

Merge api request using promise

Due to the api of a plugin I'm using not working properly. I need to merge the two different requests. I am using the thunk below.
I can get a response but I cannot seem to check for response.ok, and return the combined data:
export function fetchCategories() {
const firstPage =
"http://wordpress.rguc.co.uk/index.php/wp-json/tribe/events/v1/categories?per_page=60&page=1";
const secondPage =
"http://wordpress.rguc.co.uk/index.php/wp-json/tribe/events/v1/categories?per_page=60&page=2";
return dispatch => {
dispatch(isLoading(true));
Promise.all([fetch(firstPage), fetch(secondPage)])
.then(response => {
// check for ok here
response.ForEach(response => {
if (!response.ok) throw Error(response.statusText);
});
dispatch(isLoading(false));
return response;
})
.then(response => response.json())
// dispatch combined data here
.then(data => dispatch(fetchSuccessCategories(data)))
.catch(() => dispatch(hasErrored(true)));
};
}
Any ideas?
You are doing the check for .ok fine because it's in a loop, but your response is actually an array of two Response objects, it does not have a .json() method. You could do Promise.all(responses.map(r => r.json())), but I would recommend to write a helper function that does the complete promise chaining for one request and then call that twice:
function fetchPage(num) {
const url = "http://wordpress.rguc.co.uk/index.php/wp-json/tribe/events/v1/categories?per_page=60&page="+num;
return fetch(url).then(response => {
if (!response.ok)
throw new Error(response.statusText);
return response.json();
});
}
export function fetchCategories() {
return dispatch => {
dispatch(isLoading(true));
Promise.all([fetchPage(1), fetchPage(2)]).then(data => {
dispatch(isLoading(false));
dispatch(fetchSuccessCategories(merge(data)));
}, err => {
dispatch(isLoading(false));
dispatch(hasErrored(true));
});
};
}

Categories