Function does not wait for fetch request - javascript

I am trying to retrieve JSON from a server as an initial state.
But it looks like the function doesn't wait for the response.
I looked at different Stackoverflow posts like How to return return from a promise callback with fetch? but the answers I found didn't seem to help.
// Get the best initial state available
// 1. Check for local storage
// 2. Use hardcoded state with the test value from the server.
export function getInitialState() {
if (localStorage.getItem('Backup') != undefined) {
return returnValue = Map(JSON.parse(localStorage.getItem('Backup')))
} else {
var returnValue = initialState
const GetJSON = (url) => {
let myHeaders = new Headers();
let options = {
method: 'GET',
headers: myHeaders,
mode: 'cors'
};
return fetch(url, options).then(response => response.json());
};
GetJSON('https://example.com/api/v1/endpoint/valid/').then(result => {
// Console.log gives a good result
console.log(result)
// The return is undefined
return returnValue.setIn(['test'], result)
});
}
}
In this case, I receive an undefined while I expect a returnValue JSON where the test property is updated from the server.
So I really want the function getInitialState() to return the state. And to do this it needs to wait for the fetch to finish. I also tried to place return before the GetJSON but this had no effect.
Oke, so I just tried the following:
GetJSON('https://example.com/api/v1/endpoint/valid/').then(result => {
console.log('aaa')
console.log(result)
localstorage.setItem('init', result)
console.log('bbb')
}).then(result => {
console.log('done')
});
This returns aaa and result.
But the localStorage is never set, and the bbb and done are never shown.

Related

Promise all with axios in react native app

I'm making a react-native weather forecast app. And I'm trying to get all the data using 2 promise all methods
This is the function I call in useEffect
async function getData(){
try{
Promise.all(_.map(savedPlaces, getCurrentWeather)).then((response) => {console.log("current", response.data)})
Promise.all(_.map(savedPlaces, getDailyWeather)).then((response) => {console.log("daily", response.data)})
}
catch(error){
console.log(error)
}
}
The savedPlaces variable is an array with names of the cities I want to get the weather for
And this is one of the two fuctions i use to get the data
const getCurrentWeather = async (places) =>{
const options = {
method: 'GET',
url: 'https://community-open-weather-map.p.rapidapi.com/weather',
params: {q: places.name, lang: 'null', units: 'metric', mode: JSON},
headers: {
'x-rapidapi-host': 'community-open-weather-map.p.rapidapi.com',
'x-rapidapi-key': 'xxx'
}
};
const request = await axios.request(options).then(response => {console.log(response.data)})
return request
}
The other funtion is basicaly the same except little changes in options
And the issu is that I can see the data in print out in this code fragment
.then(response => {console.log(response.data)})
inside the getCurrentWeather functions but when I try to print them out in .then after Promise.all I get undefined, same with the other function.
current [undefined, undefined]
And I'm asking how to properly do it
Here:
const request = await axios.request(options)
.then(response => {console.log(response.data)})
The callback under then prints the data in the console, but has no return statement (returns undefined). Therefore this
return request
returns undefined wrapped in a promise.
Add return response (or return response.data) after the console.log and it should get better.

How do I nest callbacks for async functions in javascript? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I've looked but haven't been able to find a solution to this specific problem, so I thought I'd ask. I'm a novice javascript developer who clearly needs to read more about scope, callbacks and promises.
I'm trying to nest callbacks to get data out of a http request using the fetch API in javascript. At this point in my project, I've sent data to a node back end, called a few apis, then sent json data back to the client.
I now want to access that data outside of the function getServerData in the below.
I've tried a few different things but haven't been able to figure it out. I feel like I'm missing something obvious.
My current code is below:
//I want to access callback data here
const getServerData = userData => {
// declare data to send
const apiData = userData;
// declare route
const url = 'http://localhost:3030/nodeserver';
// declare POST request options
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(apiData)
};
// Async function to fetch from Node server w/ callback
const fetchUIData = async callback => {
await fetch(url, options)
.then(response => response.json())
.then(data => {
callback(data);
})
.catch(err =>
console.log(
`There was an error fetching from the API POST route:${err}`
)
);
};
// Variable to store callback data
let serverData = [];
// Callback function to use data from fetch
return fetchUIData(data => {
serverData = data;
console.log(serverData);
});
};
You don't nest callbacks when using await. The whole point of await is to get rid of the .then( .then( .then())) callback hell and nesting. Either use .then() (if you enjoy callback hells :) or await; not both together, it doesn't make sense.
const getServerData = async userData => {
const url = 'http://localhost:3030/nodeserver';
const options = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
};
const response = await fetch(url, options);
return response.json()
};
const serverData = await getServerData(userData);
console.log(serverData); // <-- Tadaaa
As soon as the result is based on some asynchronous work, you need to return it using a Promise or a callback.
So const getServerData = userData => { has to either accept a callback, or to return a Promise.
The callback in that part of your code does not seem to have any purpose:
return fetchUIData(data => {
serverData = data;
console.log(serverData);
});
It seems as if you just want to return data from getServerData
So also that part does not make any sense:
.then(data => {
callback(data);
})
So the code could look like this:
const getServerData = userData => {
// declare data to send
const apiData = userData;
// declare route
const url = 'http://localhost:3030/nodeserver';
// declare POST request options
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(apiData)
};
// Async function to fetch from Node server w/ callback
const fetchUIData = () => {
return fetch(url, options)
.then(response => response.json())
.catch(err =>
console.log(
`There was an error fetching from the API POST route:${err}`
)
return null;
);
};
// Callback function to use data from fetch
return fetchUIData()
};
But even that could be simplified:
const getServerData = async userData => {
// declare data to send
const apiData = userData;
// declare route
const url = 'http://localhost:3030/nodeserver';
// declare POST request options
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(apiData)
};
// fetch from Node server
try {
let response = await fetch(url, options)
return response.json()
} catch( err ) {
console.log(
`There was an error fetching from the API POST route:${err}`
)
return null;
}
};
The whole try-catch block is probably also something you want to remove, letting the error propagate. In the current form, the getServerData will always fulfill and only log the error. That's in many cases not what you want. But that depends on the exact use case.
The function is then used that way:
let data = await getServerData();

Return fetch .json inside object.

I have an API calling function that I would like to return the response.json() content as well as the response.status together in a single object.
Like so:
const getData = data => {
return fetch('/api_endpoint',{
method: 'GET',
headers: {
'Content-type': 'application/json'
}
})
.then(response => {
return {
body: response.json(),
status: response.status
}
})
}
The trouble is that response.json() is a promise, so I can't pull it's value until it's resolved.
I can hack around it by doing this:
const getData = data => {
let statusRes = undefined;
return fetch('/api_endpoint',{
method: 'GET',
headers: {
'Content-type': 'application/json'
}
})
.then(response => {
statusRes = response.status;
return response.json()
})
.then(data => {
return {
body: data,
status: statusRes
}
}
)
}
But it just feels WRONG. Anybody have a better idea?
const getData = data => {
return fetch('/api_endpoint',{
method: 'GET',
headers: {
'Content-type': 'application/json'
}
})
.then(async response => {
return {
body: await response.json(),
status: response.status
}
})
}
es6
async/await
might help it look more clean
There is no need for the variable if it bothers you, you can return tuples (array in ES).
In this case variable is save enough since it's used only once and within the same promise stack.
const getData = data => {
return fetch('/api_endpoint',{
method: 'GET',
headers: {
'Content-type': 'application/json'
}
})
.then(response =>
//promise all can receive non promise values
Promise.all([//resolve to a "tuple"
response.status,
response.json()
])
)
.then(
/**use deconstruct**/([status,body]) =>
//object literal syntax is confused with
// function body if not wrapped in parentheses
({
body,
status
})
)
}
Or do as Joseph suggested:
const getData = data => {
return fetch('/api_endpoint',{
method: 'GET',
headers: {
'Content-type': 'application/json'
}
})
.then(response =>
response.json()
.then(
body=>({
body,
status:response.status
})
)
)
}
update
Here I would like to explain why using await can lead to functions that do too much. If your function looks ugly and solve it with await then likely your function was doing too much to begin with and you didn't solve the underlying problem.
Imagine your json data has dates but dates in json are strings, you'd like to make a request and return a body/status object but the body needs to have real dates.
An example of this can be demonstrated with the following:
typeof JSON.parse(JSON.stringify({startDate:new Date()})).startDate//is string
You could say you need a function that goes:
from URL to promise of response
from promise of response to promise of object
from promise of object to promise of object with actual dates
from response and promise of object with actual dates to promise of body/status.
Say url is type a and promise of response is type b and so on and so on. Then you need the following:
a -> b -> c -> d ; [b,d]-> e
Instead of writing one function that goes a -> e it's better to write 4 functions:
a -> b
b -> c
c -> d
[b,d] -> e
You can pipe output from 1 into 2 and from 2 into 3 with promise chain 1.then(2).then(3) The problem is that function 2 gets a response that you don't use until function 4.
This is a common problem with composing functions to do something like a -> e because c -> d (setting actual dates) does not care about response but [b,d] -> e does.
A solution to this common problem can be threading results of functions (I'm not sure of the official name for this in functional programming, please let me know if you know). In a functional style program you have types (a,b,c,d,e) and functions that go from type a to b, or b to c ... For a to c we can compose a to b and b to c. But we also have a function that will go from tuple [b,d] to e
If you look at the 4th function objectAndResponseToObjectAndStatusObject it takes a tuple of response (output of 1st function) and object with dates (output of 3rd function) using a utility called thread created with createThread.
//this goes into a library of utility functions
const promiseLike = val =>
(val&&typeof val.then === "function");
const REPLACE = {};
const SAVE = {}
const createThread = (saved=[]) => (fn,action) => arg =>{
const processResult = result =>{
const addAndReturn = result => {
(action===SAVE)?saved = saved.concat([result]):false;
(action===REPLACE)?saved = [result]:false;
return result;
};
return (promiseLike(result))
? result.then(addAndReturn)
: addAndReturn(result)
}
return (promiseLike(arg))
? arg.then(
result=>
fn(saved.concat([result]))
)
.then(processResult)
: processResult(fn(saved.concat([arg])))
};
const jsonWithActualDates = keyIsDate => object => {
const recur = object =>
Object.assign(
{},
object,
Object.keys(object).reduce(
(o,key)=>{
(object[key]&&(typeof object[key] === "object"))
? o[key] = recur(object[key])
: (keyIsDate(key))
? o[key] = new Date(object[key])
: o[key] = object[key];
return o;
},
{}
)
);
return recur(object);
}
const testJSON = JSON.stringify({
startDate:new Date(),
other:"some other value",
range:{
min:new Date(Date.now()-100000),
max:new Date(Date.now()+100000),
other:22
}
});
//library of application specific implementation (type a to b)
const urlToResponse = url => //a -> b
Promise.resolve({
status:200,
json:()=>JSON.parse(testJSON)
});
const responseToObject = response => response.json();//b -> c
const objectWithDates = object =>//c -> d
jsonWithActualDates
(x=>x.toLowerCase().indexOf("date")!==-1||x==="min"||x==="max")
(object);
const objectAndResponseToObjectAndStatusObject = ([response,object]) =>//d -> e
({
body:object,
status:response.status
});
//actual work flow
const getData = (url) => {
const thread = createThread();
return Promise.resolve(url)
.then( thread(urlToResponse,SAVE) )//save the response
.then( responseToObject )//does not use threaded value
.then( objectWithDates )//does no use threaded value
.then( thread(objectAndResponseToObjectAndStatusObject) )//uses threaded value
};
getData("some url")
.then(
results=>console.log(results)
);
The async await syntax of getData would look like this:
const getData = async (url) => {
const response = await urlToResponse(url);
const data = await responseToObject(response);
const dataWithDates = objectWithDates(data);
return objectAndResponseToObjectAndStatusObject([response,dataWithDates]);
};
You could ask yourself is getData not doing too much? No, getData is not actually implementing anything, it's composing functions that have the implementation to convert url to response, response to data ... GetData is only composing functions with the implementations.
Why not use closure
You could write the non async syntax of getData having the response value available in closure like so:
const getData = (url) =>
urlToResponse(url).then(
response=>
responseToObject(response)
.then(objectWithDates)
.then(o=>objectAndResponseToObjectAndStatusObject([response,o]))
);
This is perfectly fine as well, but when you want to define your functions as an array and pipe them to create new functions you can no longer hard code functions in getDate.
Pipe (still called compose here) will pipe output of one function as input to another. Let's try an example of pipe and how it can be used to define different functions that do similar tasks and how you can modify the root implementation without changing the functions depending on it.
Let's say you have a data table that has paging and filtering. When table is initially loaded (root definition of your behavior) you set parameter page value to 1 and an empty filter, when page changes you want to set only page part of parameters and when filter changes you want to set only filter part of parameters.
The functions needed would be:
const getDataFunctions = [
[pipe([setPage,setFiler]),SET_PARAMS],
[makeRequest,MAKE_REQUEST],
[setResult,SET_RESULTS],
];
Now you have the behavior of initial loading as an array of functions. Initial loading looks like:
const initialLoad = (action,state) =>
pipe(getDataFunctions.map(([fn])=>fn))([action,state]);
Page and filter change will look like:
const pageChanged = action =>
pipe(getDataFunctions.map(
([fn,type])=>{
if(type===SET_PARAMS){
return setPage
}
return fn;
}
))([action,state]);
const filterChanged = action =>
pipe(getDataFunctions.map(
([fn,type])=>{
if(type===SET_PARAMS){
return setFiler
}
return fn;
}
))([action,state]);
That demonstrates easily defining functions based on root behavior that are similar but differ slightly. InitialLoad sets both page and filter (with default values), pageChanged only sets page and leaves filter to whatever it was, filterChanges sets filter and leaves page to whatever it was.
How about adding functionality like not making the request but getting data from cache?
const getDataFunctions = [
[pipe([setPage,setFiler]),SET_PARAMS],
[fromCache(makeRequest),CACHE_OR_REQUEST],
[setResult,SET_RESULTS],
];
Here is an example of your getData using pipe and thread with an array of functions (in the example they are hard coded but can be passed in or imported).
const getData = url => {
const thread = createThread();
return pipe([//array of functions, can be defined somewhere else or passed in
thread(urlToResponse,SAVE),//save the response
responseToObject,
objectWithDates,
thread(objectAndResponseToObjectAndStatusObject)//uses threaded value
])(url);
};
The array of functions is easy enough for JavaScript but gets a bit more complicated for statically typed languages because all items in the array have to be T->T therefor you cannot make an array that has functions in there that are threaded or go from a to b to c.
At some point I'll add an F# or ReasonML example here that does not have a function array but a template function that will map a wrapper around the functions.
Use async/await. That will make things much cleaner:
async function getData(endpoint) {
const res = await fetch(endpoint, {
method: 'GET'
})
const body = await res.json()
return {
status: res.status,
body
}
}
You also might want to add a try / catch block and a res.ok check to handle any request errors or non 20x responses.

Returning data from Axios API [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 months ago.
I am trying to use a Node.JS application to make and receive API requests. It does a get request to another server using Axios with data it receives from an API call it receives. The second snippet is when the script returns the data from the call in. It will actually take it and write to the console, but it won't send it back in the second API.
function axiosTest() {
axios.get(url)
.then(function (response) {
console.log(response.data);
// I need this data here ^^
return response.data;
})
.catch(function (error) {
console.log(error);
});
}
...
axiosTestResult = axiosTest();
response.json({message: "Request received!", data: axiosTestResult});
I'm aware this is wrong, I'm just trying to find a way to make it work. The only way I can seem to get data out of it is through console.log, which isn't helpful in my situation.
The issue is that the original axiosTest() function isn't returning the promise. Here's an extended explanation for clarity:
function axiosTest() {
// create a promise for the axios request
const promise = axios.get(url)
// using .then, create a new promise which extracts the data
const dataPromise = promise.then((response) => response.data)
// return it
return dataPromise
}
// now we can use that data from the outside!
axiosTest()
.then(data => {
response.json({ message: 'Request received!', data })
})
.catch(err => console.log(err))
The function can be written more succinctly:
function axiosTest() {
return axios.get(url).then(response => response.data)
}
Or with async/await:
async function axiosTest() {
const response = await axios.get(url)
return response.data
}
Guide on using promises
Info on async functions
I know this post is old. But i have seen several attempts of guys trying to answer using async and await but getting it wrong. This should clear it up for any new references
UPDATE: May 2022
This answer is still having lots of interest and have updated it to use arrow functions
const axiosTest = async () {
try {
const {data:response} = await axios.get(url) //use data destructuring to get data from the promise object
return response
}
catch (error) {
console.log(error);
}
}
you can populate the data you want with a simple callback function,
let's say we have a list named lst that we want to populate,
we have a function that pupulates pupulates list,
const lst = [];
const populateData = (data) => {lst.push(data)}
now we can pass the callback function to the function which is making the axios call and we can pupulate the list when we get data from response.
now we make our function that makes the request and pass populateData as a callback function.
function axiosTest (populateData) {
axios.get(url)
.then(function(response){
populateData(response.data);
})
.catch(function(error){
console.log(error);
});
}
The axios library creates a Promise() object. Promise is a built-in object in JavaScript ES6. When this object is instantiated using the new keyword, it takes a function as an argument. This single function in turn takes two arguments, each of which are also functions — resolve and reject.
Promises execute the client side code and, due to cool Javascript asynchronous flow, could eventually resolve one or two things, that resolution (generally considered to be a semantically equivalent to a Promise's success), or that rejection (widely considered to be an erroneous resolution). For instance, we can hold a reference to some Promise object which comprises a function that will eventually return a response object (that would be contained in the Promise object). So one way we could use such a promise is wait for the promise to resolve to some kind of response.
You might raise we don't want to be waiting seconds or so for our API to return a call! We want our UI to be able to do things while waiting for the API response. Failing that we would have a very slow user interface. So how do we handle this problem?
Well a Promise is asynchronous. In a standard implementation of engines responsible for executing Javascript code (such as Node, or the common browser) it will resolve in another process while we don't know in advance what the result of the promise will be. A usual strategy is to then send our functions (i.e. a React setState function for a class) to the promise, resolved depending on some kind of condition (dependent on our choice of library). This will result in our local Javascript objects being updated based on promise resolution. So instead of getters and setters (in traditional OOP) you can think of functions that you might send to your asynchronous methods.
I'll use Fetch in this example so you can try to understand what's going on in the promise and see if you can replicate my ideas within your axios code. Fetch is basically similar to axios without the innate JSON conversion, and has a different flow for resolving promises (which you should refer to the axios documentation to learn).
GetCache.js
const base_endpoint = BaseEndpoint + "cache/";
// Default function is going to take a selection, date, and a callback to execute.
// We're going to call the base endpoint and selection string passed to the original function.
// This will make our endpoint.
export default (selection, date, callback) => {
fetch(base_endpoint + selection + "/" + date)
// If the response is not within a 500 (according to Fetch docs) our promise object
// will _eventually_ resolve to a response.
.then(res => {
// Lets check the status of the response to make sure it's good.
if (res.status >= 400 && res.status < 600) {
throw new Error("Bad response");
}
// Let's also check the headers to make sure that the server "reckons" its serving
//up json
if (!res.headers.get("content-type").includes("application/json")) {
throw new TypeError("Response not JSON");
}
return res.json();
})
// Fulfilling these conditions lets return the data. But how do we get it out of the promise?
.then(data => {
// Using the function we passed to our original function silly! Since we've error
// handled above, we're ready to pass the response data as a callback.
callback(data);
})
// Fetch's promise will throw an error by default if the webserver returns a 500
// response (as notified by the response code in the HTTP header).
.catch(err => console.error(err));
};
Now we've written our GetCache method, lets see what it looks like to update a React component's state as an example...
Some React Component.jsx
// Make sure you import GetCache from GetCache.js!
resolveData() {
const { mySelection, date } = this.state; // We could also use props or pass to the function to acquire our selection and date.
const setData = data => {
this.setState({
data: data,
loading: false
// We could set loading to true and display a wee spinner
// while waiting for our response data,
// or rely on the local state of data being null.
});
};
GetCache("mySelelection", date, setData);
}
Ultimately, you don't "return" data as such, I mean you can but it's more idiomatic to change your way of thinking... Now we are sending data to asynchronous methods.
Happy Coding!
axiosTest() needs to return axios.get, which in turn returns a Promise.
From there, then can be used to execute a function when said Promise resolves.
See Promise for more info.
Alternatively, await can be used from within the scope of some async function.
// Dummy Url.
const url = 'https://jsonplaceholder.typicode.com/posts/1'
// Axios Test.
const axiosTest = axios.get
// Axios Test Data.
axiosTest(url).then(function(axiosTestResult) {
console.log('response.JSON:', {
message: 'Request received',
data: axiosTestResult.data
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
IMO extremely important rule of thumb for your client side js code is to keep separated the data handling and ui building logic into different funcs, which is also valid for axios data fetching ... in this way your control flow and error handlings will be much more simple and easier to manage, as it could be seen from this
ok fetch
and this
NOK fetch
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function getUrlParams (){
var url_params = new URLSearchParams();
if( window.location.toString().indexOf("?") != -1) {
var href_part = window.location.search.split('?')[1]
href_part.replace(/([^=&]+)=([^&]*)/g,
function(m, key, value) {
var attr = decodeURIComponent(key)
var val = decodeURIComponent(value)
url_params.append(attr,val);
});
}
// for(var pair of url_params.entries()) { consolas.log(pair[0]+ '->'+ pair[1]); }
return url_params ;
}
function getServerData (url, urlParams ){
if ( typeof url_params == "undefined" ) { urlParams = getUrlParams() }
return axios.get(url , { params: urlParams } )
.then(response => {
return response ;
})
.catch(function(error) {
console.error ( error )
return error.response;
})
}
// Action !!!
getServerData(url , url_params)
.then( response => {
if ( response.status === 204 ) {
var warningMsg = response.statusText
console.warn ( warningMsg )
return
} else if ( response.status === 404 || response.status === 400) {
var errorMsg = response.statusText // + ": " + response.data.msg // this is my api
console.error( errorMsg )
return ;
} else {
var data = response.data
var dataType = (typeof data)
if ( dataType === 'undefined' ) {
var msg = 'unexpected error occurred while fetching data !!!'
// pass here to the ui change method the msg aka
// showMyMsg ( msg , "error")
} else {
var items = data.dat // obs this is my api aka "dat" attribute - that is whatever happens to be your json key to get the data from
// call here the ui building method
// BuildList ( items )
}
return
}
})
</script>
After 6 hours of fluttering, I realized it was a one-line problem. If you are interfering with the axios life-cycle, you may have forgotten this line:
componentDidMount() {
this.requestInterceptor = axios.interceptors.request.use((request) => {
this.updateApiCallFor(request.url, true);
return request;
});
this.responseInterceptor = axios.interceptors.response.use((response) => {
this.updateApiCallFor(response.config.url, false);
return response; // THIS LINE IS IMPORTANT !
}, (error) => {
this.updateApiCallFor(error.config.url, false);
throw error;
});
async makes a function return a Promise
await makes a function wait for a Promise
code async/await
// https://www.npmjs.com/package/axios
const axios = require('axios')
/* --- */
async function axiosTest() {
let promiseAxios = axios.get( 'https://example.com' )
/* --- */
console.log( await promiseAxios )
}
/* --- */
axiosTest()
replit.com Stackoverflow - Returning data from Axios API
replit.com Stackoverflow - How to return values from async
code async/await with return
// https://www.npmjs.com/package/axios
const axios = require('axios')
/* --- */
async function axiosTest() {
console.log( await promiseAxios() )
}
/* --- */
axiosTest()
/* --- */
// create function for promise axios and return it
function promiseAxios() {
return axios.get( 'https://example.com' )
}
replit.com Stackoverflow - Returning data from Axios API - return
replit.com Stackoverflow - How to return values from async - return
Try this,
function axiosTest() {
axios.get(url)
.then(response => response.data)
.catch(error => error);
}
async function getResponse () {
const response = await axiosTest();
console.log(response);
}
getResponse()
It works, but each function where you want to get the response needs to be an async function or use an additional .then() callback.
function axiosTest() {
axios.get(url)
.then(response => response.data)
.catch(error => error);
}
async function getResponse () {
axiosTest().then(response => {
console.log(response)
});
}
getResponse()
If anyone knows a way to avoid this please do tell.
Also checkout Katsiaryna (Kate) Lupachova's article on Dev.to. I think it will help.
async handleResponse(){
const result = await this.axiosTest();
}
async axiosTest () {
return await axios.get(url)
.then(function (response) {
console.log(response.data);
return response.data;})
.catch(function (error) {
console.log(error);
});
}
You can find check https://flaviocopes.com/axios/#post-requests url and find some relevant information in the GET section of this post.
You can use Async - Await:
async function axiosTest() {
const response = await axios.get(url);
const data = await response.json();
}

Why does fetch return a weird hash of integers?

I'm using fetch API with React Native.
My response follows a normal format of {"message": "error here"} if the status is >= 400, which I will show in a native popup.
I'm trying to call response.json() after detecting a failure, but it keeps putting everything in a weird format...
{ _45: 0, _81: 0, _65: null, _54: null }
For whatever reason... the actual response I want is located in _65... I have no idea what these random keys are.
So currently I'm having to access it via _bodyText, but I assume that is wrong because it's a private underscore method.
What am I doing wrong?
var API = (function() {
var base = 'https://example.com/api/v1';
var defaults = {
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
};
var alertFailure = function(response) {
if (response.status >= 200 && response.status < 400) {
return response;
} else {
var json = JSON.parse(response._bodyText || '{}');
var message = json.message || 'There was a problem. Close the app, and try again later.';
var error = new Error(message);
error.response = response;
throw error;
}
};
var callAPI = function(url, opts) {
opts.headers['X-Version'] = 'v' + Package.version;
return fetch(base + url, opts)
.then(alertFailure)
.then((response) => {
return response.json();
})
.catch((error) => {
Alert.alert(null, error.message);
});
};
return {
get: function(url, opts) {
var fullOpts = Object.assign({}, defaults, opts);
return callAPI(url, fullOpts);
},
post: function(url, data, opts) {
var fullOpts = Object.assign({}, defaults, {
method: 'POST',
body: JSON.stringify(data || {})
}, opts);
return callAPI(url, fullOpts);
}
};
})();
The answer is that .json() returns a promise... so I had to do everything from within .then()
AsyncStorage.getItems always returns a promise. You can use this method below
AsyncStorage.getItem("access_key").then((value)=>
{
console.log(value);
});
I would recommend you to use the new ES7 syntax async/await, they are easier to understand than using .then()
To use it, just declare some method with the async prefix and inside of it use await to wait for the call to finish.
E.g
async someMethod(){
result = await fetch(URL); // Do some request to any API.
// Use the result after that knowing that you'll have it completed.
}
I hope this helps, at least in my opinion, I find this easier than using .then(), especially when you have to do multiple calls within the same method.

Categories

Resources