Promise Never Resolves Using Axios - javascript

I am using WDIO and defining a customer reporter to integrate with the testrails api. The plan was to use axios to make these requests inside the testing hooks.
Unfortunately, I am unable to get axios to return any valid data on requests. In most cases when we await a response, the thread just stops executing entirely without any logging output. If I jimmy it enough sometimes I can get it to return an unresolved promise, but nothing I can do ultimately resolves the promise.
Also in none of my attempts have the requests been received by testrails (I've tested a few other urls as well, I'm fairly certain the issue is not at the destination).
I've made sure that network access and security are not factors. We have also attempted using both the axios post, and the straight up axios() methods, no luck there.
I'll copy the file below, I've added roughly a dozen attempts/configurations with notes on each as to what we're getting. The meat of the issue is in the addRun() method.
In most cases we never appear to resolve the promise. there is one exception, where we don't interact at all with the response, just log inside the then() statement. If we do that, we can see those logs, but the results of the axios call never take effect (the run is not created in testrails).
const WDIOReporter = require('#wdio/reporter').default
const axios = require('axios').default;
module.exports = class TestrailsReporter extends WDIOReporter{
constructor(options) {
/*
* make reporter to write to the output stream by default
*/
options = Object.assign(options, { stdout: true })
super(options)
}
// I have tried marking this as both async and not, no difference
async onRunnerEnd(suite) {
console.log("CHECKPOINT RUNNER END")
this.recordResults(caseIds[5], results[5], 'renters api tests', 5);
}
/**
* takes the results from a test suite and records them in testrails
* #param suiteId -- the suite defined in the testrails project
* #param projectId -- the project id defined in the testrails project
* #param caseIds -- a list of cases with which to create the test run
* #param results -- a list of case:result pairings
*/
async recordResults(caseIds, results, name, projectId) {
console.log(`CHECKPOINT RECORDING RESULTS ${projectId}`)
let testRun = await this.addRun(results['suiteId'], caseIds['cases'], name, projectId);
testRun.then(console.log)
await this.addResults(testRun, results['cases']);
}
async addRun(suiteId, caseIds, name = '', projectId) {
console.log("CHECKPOINT ADD RUN")
let addRunConfig = {
method: 'post',
url: `https://REDACTED.testrail.io/index.php?/api/v2/add_run/${projectId}`,
headers: {
'Content-Type': 'application/json',
Authorization: token,
Cookie: 'tr_session=041c4349-688f-440a-95a3-afc29d39320a'
},
data: JSON.stringify({
suite_id: suiteId,
include_all: false,
case_ids: caseIds,
name: name
})
};
// let x = axios.get('https://www.google.com/')
// console.log(x)
axios.defaults.timeout = 1000;
// THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT, RETURNS PENDING PROMISE TO RESPONSE
// let response = axios(addRunConfig)
// .then(function (response) {
// console.log("WHAAAT?")
// return response.data.id;
// })
// .catch(function (error) {
// console.log("HELP!")
// console.log(error);
// });
// THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT, NO LOGGING APPEARS AFTER
let response = await axios(addRunConfig)
.then(function (response) {
console.log("WHAAAT?")
return response.data.id;
})
.catch(function (error) {
console.log("HELP!")
console.log(error);
});
// THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT
// await axios.post(`https://REDACTED.testrail.io/index.php?/api/v2/add_run/${projectId}`, addRunConfig)
// .then(
// function (response){
// console.log('WHAAAT?')
// console.log(response)
// console.log('NO WAY?')
// })
// THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT, BUT RETURNS A PENDING PROMISE TO RESPONSE
// let response = axios.post(`https://REDACTED.testrail.io/index.php?/api/v2/add_run/${projectId}`, addRunConfig)
// .then(
// function (run){
// console.log('WHAAAT?')
// console.log(run)
// console.log('NO WAY?')
// })
// THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT, BUT RETURNS A PENDING PROMISE TO RESPONSE
// let response = axios.post(`https://REDACTED.testrail.io/index.php?/api/v2/add_run/${projectId}`, addRunConfig)
// .then(
// function (run){
// console.log('WHAAAT?')
// })
// THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT, BUT RETURNS A PENDING PROMISE TO RESPONSE
// let response = axios.post(`https://REDACTED.testrail.io/index.php?/api/v2/add_run/${projectId}`, addRunConfig)
// .then(run => {
// console.log('WHAAAT?')
// })
// THIS EXECUTES THE CONSOLE.LOG INSIDE THE THEN STATEMENT, BUT NOT AFTER
// let response = await axios.post(`https://REDACTED.testrail.io/index.php?/api/v2/add_run/${projectId}`, addRunConfig)
// .then(console.log('WHAAAT?'))
// THIS EXECUTES THE CONSOLE.LOG INSIDE THE THEN STATEMENT, AND AFTER
// let response = axios.post(`https://REDACTED.testrail.io/index.php?/api/v2/add_run/${projectId}`, addRunConfig)
// .then(console.log('WHAAAT?'))
// EXECUTES THE CONSOLE.LOG INSIDE THE THEN STATEMENT, NOTHING FROM THE CATCH, AND NOTHING AFTER
// const response = await axios(addRunConfig).then(console.log("HI")).catch(function (error) {
// console.log("HELP!")
// console.log(error);
// });
console.log("ANYTHING")
console.log(response)
return response
}```

Figured this out, it was the WDIOReporter parent class not playing nice with the asynchronous calls from axios. Solution found here:
https://github.com/webdriverio/webdriverio/issues/5701

Have you tried calling the method using
await axios.post(...) instead of defining everything in the addRunConfig object?
Not sure if it makes a difference, but it's something to try.

There is some confusion around the concepts of defining functions, calling functions and asynchronous functions here.
First of all: If you are calling an asynchronous function and do not want your calling function to return before that asynchronous function has returned, you want to await that call.
In this case, your recordResults function awaits something, and is thus async. Therefor, you probably want that onRunnerEnd awaits your call to recordResults. If you dont do that, the function will terminate prematurely and likely not wait for a result.
async onRunnerEnd(suite) {
console.log("CHECKPOINT RUNNER END")
await this.recordResults(caseIds[5], results[5], 'renters api tests', 5);
}
Secondly, if you use then and await together, the value returned by the await expression is whatever the function inside the then returns. Thus, all your attempts that have no return value inside the function called by then will never return anything but a void promise. There is no reason to combine these concepts.
Thirdly, putting a function call (rather than a declaration or reference) inside a then clause, will immediately call that function. I.e. .then(console.log('WHAAAT?')) just immediately calls console.log and also registers a non existent function as the callback for then (since console.log does not return a function reference).
Lastly, passing unbound functions is not going to work in general. Doing things like testRun.then(console.log) will not work, depending on the implementation of then and console.log. Either do testRun.then(console.log.bind(console) or testRun.then((x) => console.log(x)) to be on the safe side.
So, first of all, add that await inside onRunnerEnd, and then just use the await result without any then or catch in your addRun:
async addRun(suiteId, caseIds, name = '', projectId) {
console.log("CHECKPOINT ADD RUN")
let addRunConfig = {
method: 'post',
url: `https://REDACTED.testrail.io/index.php?/api/v2/add_run/${projectId}`,
headers: {
'Content-Type': 'application/json',
Authorization: token,
Cookie: 'tr_session=041c4349-688f-440a-95a3-afc29d39320a'
},
data: JSON.stringify({
suite_id: suiteId,
include_all: false,
case_ids: caseIds,
name: name
})
};
// let x = axios.get('https://www.google.com/')
// console.log(x)
axios.defaults.timeout = 1000;
let response = await axios(addRunConfig);
console.log(response);
console.log(response.data.id);
return response.data.id;
}

Related

Nodejs: process exits while promise is pending

Excerpt of a lambda function using nodejs 12.
There is a promise (aws dynamo db document client query) nested inside a promise (node-fetch API request).
The first promise works fine. It executes the request, waits for the promise to resolve, and then enters the .then(...) to execute some code. Next, it executes the database query, but then it exits the whole function without waiting for the promise to resolve, even though there are still callbacks. It doesn't throw errors either. (I know the database query is being executed , as extra logging showed it's status to be <pending>)
When I try var dbscan = await db.scan(...) using await, I get the error await is only valid in async function. But the handler function is already async, and await is working for the fetch promise.
Q: how can I use await inside the .then(...) of the first promise?
Q: why is the process exiting without waiting for the promise to resolve?
exports.myhandler = async (event, context, callback) => {
var response = await fetch(url, {... my options ...})
.then(res => res.text())
.then(data => {
// do some stuff with the data ...
var dbscan = db.scan({...my params ...}).promise()
.then(res => {
// do some stuff with result ...
callback(null, <some message>);
}).catch(err => {
console.log(err);
callback(null, <some message>);
});
})
.catch(error => {
console.log('error', error);
callback(null, <some message>);
});
}
You have to add async to the beginning of the function in which you want to use await.
.then(async(data) => {
var dbscan = await ...
})
Since you're already using the async/await-syntax, you shouldn't have to resolve to using .then(..) chains.
You could flatten most of your code like this:
const response = await fetch(url, {... my options ...});
const data = await response.text();
// Do some stuff with the data...
const result = await db.scan({...my params ...});
// Do some stuff with the result...

How to execute asynchronous code in Javascript

I've looked into MDN web docs article on async functions and for some reason it doesn't work for me
Here's my code
function createObject() {
try {
console.log("Processing POST Loan.");
var data = {
"value1" : 1288,
"value2" : [{
"value3" : 3833,
"value4": [{
"value5": new Date()
}]
}]
}
var auth = Buffer.from("login:pass").toString('base64')
const res = request("http://url.com/resource", {
method: "POST",
headers: {
'Content-Type': 'application/json',
'Authorization': "Basic "+auth
},
body: JSON.stringify(data)
}, function(error, response, body){
//console.log(response + ' '+body)
})
var response = res.body.id;
return response
}
catch(err) {
throw err
}
}
async function uploadReport() {
console.log('cerate object')
var objectId = await createObject();
console.log('object = '+objectId)
}
uploadReport()
Exactly as described in the article. But when I run my script I get this result:
cerate object
Processing POST Loan.
'data {"value1":1288,"value2":[{"value3":3833,"value4":[{"value5":"2021-10-05T09:45:46.126Z"}]}]}'
'auth '
object = undefined
Then nothing happens for a few seconds and execution stops. Http request works fine and objects are being created as I run the script, though I don't get any response (this API should return auto generated object ID). What am I doing wrong here?
I'm assuming you are quite new to JS programming and it seems you lack a little understanding about how the flow of execution works for async code.
In JS, async code works in promises. Promises are the way JS represents code that eventually will yield a value (or void, but it's the same).
So now we need a way to control the flow of execution. This means, we should be able to execute code that depends on that result after we have gotten that result. Or in other words, we should wait for the promise to resolve and then execute the code that depended on it.
Enter callbacks. Callbacks is how this is done in JS (before async/await appeared, but let's not get ahead of ourselves). As functions are first class citizens in JS we can declare them and pass them around as function arguments. So, in those terms, a callback it's the code that should be executed after the promise has given us its result.
When it comes to callbacks, me personally I have seen two ways of dealing with them.
A first approach, function expects such callback as an argument. Usually (but it doesn't have to be like this) the first arguments are the actual arguments necessary to perform the task, and the last one is the callback: what to do after the task is done. Example:
// A function that receives an `arguments` object and a `callback` function.
// Observe
function doSomethingAsynchronous(arguments, callback) {
const a = arguments.a
const b = arguments.b
const result = a + b //this is not asynchronous, only to illustrate.
callback(result)
}
You would use this function like this:
doSomethingAsynchronous({a:2, b:3}, (result)=>{
console.log(`The result was ${result}`)
})
Note how doSomethingAsynchronous does not return anything; the flow of execution is directed towards the callback.
A second approach might be a function that returns an actual Promise. Promises have a then() method and a catch() method. These are used to chain more code after the resolution of the Promise:
function iReturnAPromise(arguments) {
return new Promise((resolve, reject) => {
const result = arguments.a + arguments.b;
resolve(result);
})
}
You would manage the flow of execution by doing so:
const promiseOfTheResult = iReturnAPromise({a: 2, b:2})
promiseOfTheResult.then((result) => {console.log(result)})
// You'll never see it like that. You'll always see:
iReturnAPromise({a:2, b:3}).then((result) => {console.log(result)})
And last, but definitely not least, came async/await which simplified the use of promises. With async await, you would declare iReturnAPromise just the same, but you would use it like so;
const result = await iReturnAPromise({a:1, b:2})
console.log(result)
Notice how this last method keeps the code in line and avoids the callback hell. Also notice how functions that don't return a promise cannot be awaited, they first have to be "promisified": that is, wrapping them in a promise.
Let's start from the begining since you seem a little confused.
What you want to do is to make an async call from a callback kind of function ('request'). For that, you must use Promise.
So your createObject function must return a new Promise object, or must be declared as an async function. In your case, since the request function use a callback pattern, you have to use a Promise object because it will provide you a callback that must be called when your Promise resolve.
function createObject() {
return new Promise((resolve, reject) => {
try {
console.log("Processing POST Loan.");
var data = {
"value1" : 1288,
"value2" : [{
"value3" : 3833,
"value4": [{
"value5": new Date()
}]
}]
}
var auth = Buffer.from("login:pass").toString('base64')
const res = request("http://url.com/resource", {
method: "POST",
headers: {
'Content-Type': 'application/json',
'Authorization': "Basic "+auth
},
body: JSON.stringify(data)
}, function(error, response, body){
if(error) reject(error);
resolve({ response, body });
});
}
catch(err) {
reject(err);//the promise is rejected
}
});
}
async function uploadReport() {
console.log('cerate object')
const res = await createObject();
//in res you get 'response' and 'body' where you have the result of your API.
//it's up to you to adapt this to what you want
console.log(res);
}
uploadReport()

Not using Promise returned by fetch()

Is (3) a correct way of using then()?
I don't need the Promise returned by fetch(), I just want obtain an updated array of emails once fetch() is done.
Are my comments for (1) (2) and (3) correct? I tested them by running another then() (4) after each of them, and they seem right. I just want to be sure.
function setArchive(email_id, boolArchive) {
fetch(`/emails/${email_id}`, {
method: 'PUT',
body: JSON.stringify({
archived: boolArchive
})
})
##### (Using just one of these at a time)
(1) .then(load_mailbox('inbox')) // doesn't wait for fetch() to resolve, returned Promise accessible by the next then()
(2) .then((response) => load_mailbox('inbox')) // waits for fetch(), returned Promise NOT accessible by the next then() (4)
(3) .then(() => load_mailbox('inbox')) // waits for fetch(), returned Promise NOT accessible by the next then() (4)
#####
(4) .then(response => console.log(response)) // (2) and (3) logs 'undefined'
Thanks for your help.
Ok, I think you are saying that you want to do something conditional.
i.e. you want to do one of three things when the fetch completes?
I recommend you have a fetch that takes optional.
In the demo below we accept a url and an Array of functions to execute once the fetch is complete. In the way we could pass different functions to the method when we are looking to do different tasks. I mixed up sync and async just for demonstration.
// Lets have three methods
const postFetchOne = async (json) => {
console.log(JSON.stringify(json));
};
const postFetchTwo = (json) => {
document.querySelector('pre').innerHTML = JSON.stringify(json, 3);
};
const doSomethingDifferent = async (json) => {
console.log(`Received JSON - Length ${JSON.stringify(json).length}`);
};
// Now our actual fetch
const goGetJSON = async (url, funcs) => {
const todo = Array.isArray(funcs) ? funcs : [funcs];
const json = await (await fetch(url)).json();
// Now run each function
todo.forEach(f => f(json));
};
const testURL = 'https://jsonplaceholder.typicode.com/todos/1';
goGetJSON(testURL,
[postFetchOne, postFetchTwo]);
// lets do something different
goGetJSON(testURL, doSomethingDifferent);
<pre></pre>

My asynchronous javascript gets executed in the middle of the other function

Im trying to execute a function after the other one in Vue.js. I've already tried async/await, callback functions, .then, but it somehow doesnt want to load one after the other. What is a possible solution?
auth_mixin.js:
async auth () {
console.log("authban")
var token = this.getCookie("token")
var jsonData = {}
jsonData["token"] = token
console.log(jsonData)
var bodyFormData = new FormData();
bodyFormData.append('data', JSON.stringify(jsonData));
axios({
method: 'post',
url: 'backend/index.php?action=checkAuth',
data: bodyFormData,
headers: {'Content-Type': 'multipart/form-data'}
})
.then(function (response) {
console.log(response);
if(response.data.status==="OK"){
console.log("ok")
return true;
}else{
console.log("nem ok")
return false;
}
})
.catch(function (response) {
console.log(response);
return false;
});
}
Navbar.vue:
created () {
var result=false
this.auth().then(this.checkIfLoggedIn(result))
},
methods: {
checkIfLoggedIn (isLoggedIn) {
console.log("na ez lesz az erdekes "+isLoggedIn)
if(isLoggedIn === true){
console.log("true")
document.getElementById("logged_out").style.display="none";
document.getElementById("logged_in").style.display="block";
}else{
console.log("fail");
}
}
}
this.auth().then(this.checkIfLoggedIn(result))
You have two problems.
First: this.checkIfLoggedIn(result) calls checkIfLoggedIn immediately. You need to pass a function to then.
this.auth().then(() => this.checkIfLoggedIn(result))
Second: With that change, you call checkIfLoggedIn when auth resolves.
So when does auth resolve? Well, it is defined with the async keyword, so it resolves when it returns (unless it returns a promise, in which case it adopts that promise instead).
So what does it return? It has no return statement, so it returns undefined when it gets to the end … which is immediately after the call to axios (since you aren't awaiting that).
If you returned the return value of axios(...).etc then it wouldn't resolve until that promise resolved.
(Aside: You're using async, you should probably refactor to use await, try {} catch() {} instead of .then() and .catch()).

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

Categories

Resources