I have a code like the following
function getData()
{
for(var i=0; i<someLength; i++)
{
if(i===0)
{
response = callApi(someValue[i]);
}
else if(i===1)
{
responseInsert = callWebSocket(response, someValue[i]);
}
}
}
function callApi(insertData)
{
axios({
method: 'post',
url: 'http://localhost:1130/services/request',
data: insertData,
headers: { 'content-type': 'application/xml;charset=utf-8' }
}).then(function (response) {
console.log(response);
retVal = true;
return retVal;
}).catch(function (error) {
console.log(error);
});
}
In this, response is needed for callWebsocket function with a array's value, that should be achieved through loop. But callWebSocket function gets called before the response comes due to the asynchronous nature of node js. But I have a use case to use server side scripting and I choose node js. Any help to execute the functions synchronously with the loop in place will save me.
You need to modify the callApi method a bit. Try this:
async function getData()
{
for(var i=0; i<someLength; i++)
{
if(i===0)
{
response = await callApi(someValue[i]);
}
else if(i===1)
{
responseInsert = callWebSocket(response, someValue[i]);
}
}
}
function callApi(insertData)
{
return axios({
method: 'post',
url: 'http://localhost:1130/services/request',
data: insertData,
headers: { 'content-type': 'application/xml;charset=utf-8' }
});
}
Related
I have a forward navigation function, which triggers an async API call on certain stages, where it is required that it does not proceed (move forward) until said API call is finished (it triggers a processor in the background required for the following stages).
My issue is that it continues to proceed, despite the call not yet being completed. I'm confused at to the best and most suggested way to implement this, and would be happy for any advice.
Code:
async postData(url = "", data = {}) {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
},
forwardTicketId(ticketId) {
const origin = new URL(window.location.href).origin;
const addr = `${origin}/current_ticket_id`;
this.postData(`${addr}`, {
data: ticketId,
});
},
goNext() {
if (this.isRequiredStage) { # this needs to complete before anything else runs
this.forwardTicketId(this.ticketId);
}
this.navGoNext();
},
How the goNext function is called:
<div class="level-right">
<TicketStepsNavButtons
#goPrev="goPrev"
#goNext="goNext"
/>
</div>
Use await in the calls too.
async postData(url = "", data = {}) {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
// you can return the response if you need it
return response;
},
forwardTicketId(ticketId) {
const origin = new URL(window.location.href).origin;
const addr = `${origin}/current_ticket_id`;
// return to chain the next promises, you can async/await instead if you don't care about the result
return this.postData(`${addr}`, {
data: ticketId,
});
},
async goNext() {
if (this.isRequiredStage) { // this needs to complete before anything else runs
// await here
await this.forwardTicketId(this.ticketId);
}
this.navGoNext();
},
I want to return the ajax returned value in back to my function where it was called but no data was returned.
function payment {
var x = payment_status(status)
}
function payment_status (status)
{
return $.ajax({
url: "http://127.0.0.1:81/public/api/payment_status",
type: 'POST',
'content-type':'application/X-WWW-form-urlencoded',
'Accept': 'application/json',
data: {
'status' : status,
}, success: function(response){}
});
}
$.ajax() returns a thenable or a Promise (in jquery 3+) See https://www.promisejs.org/ or Promise on MDN (or maybe this answer)
So you can use an async function (but maybe transpile it with babel):
async function payment() {
try {
var response = await payment_status(status);
} catch (error) {
// Handle error
}
}
function payment_status(status) {
return $.ajax({
url: "http://127.0.0.1:81/public/api/payment_status",
type: "POST",
"content-type": "application/X-WWW-form-urlencoded",
Accept: "application/json",
data: {
status: status
});
}
I don't know if it's possible, but i'm trying to get multiple ajax responses and access it's values in another function.
I actually get the responses (twice each), but i'm not able to return the responses individual values.
JSFiddle
function firstResponse() {
const response1 = $.ajax({
url: 'https://cors-anywhere.herokuapp.com/http://api.icndb.com/jokes/random',
method: 'GET',
contentType: 'application/json',
});
response1.done(function(response1) {
test(response1);
})
}
function secondResponse() {
const response2 = $.ajax({
url: 'https://cors-anywhere.herokuapp.com/https://official-joke-api.appspot.com/random_joke',
method: 'GET',
contentType: 'application/json',
});
response2.done(function(response2) {
test(response2);
})
}
firstResponse();
secondResponse();
function test(response1, response2) {
console.log('Response 1', response1);
console.log('Response 2', response2);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
There are various ways to achieve that. I personally would go with promises.
function firstResponse() {
return $.ajax({
url: 'https://cors-anywhere.herokuapp.com/http://api.icndb.com/jokes/random',
method: 'GET',
contentType: 'application/json'
});
}
function secondResponse() {
return $.ajax({
url: 'https://cors-anywhere.herokuapp.com/https://official-joke-api.appspot.com/random_joke',
method: 'GET',
contentType: 'application/json'
});
}
function test() {
Promise.all([
firstResponse(),
secondResponse()
]).then(result => {
console.log(result);
});
}
test();
In the test function you call a Promise.all which waits for all the individual promises to be resolved and outputs the result as an array in the order the of the promises passed to it at the time of calling.
let urls = ['https://cors-anywhere.herokuapp.com/http://api.icndb.com/jokes/random',
'https://cors-anywhere.herokuapp.com/https://official-joke-api.appspot.com/random_joke'];
let structure = {
method: 'GET',
contentType: 'application/json',
};
async function first() {
try {
const response = await $.ajax({
url: urls[0],
structure,
});
return response;
} catch(error) {
// Error
}
}
async function second() {
try {
const response = await $.ajax({
url: urls[1],
structure,
});
return response;
} catch(error) {
// Error
}
}
async function test() {
let response = await ('s')
return response
}
first()
.then(() => second());
Ajax calls are asynchronous so if you want to handle the two results in one function you have to do a counter yourself, something like this for the simplest kind:
function firstResponse() {
const response1 = $.ajax({
url: 'https://cors-anywhere.herokuapp.com/http://api.icndb.com/jokes/random',
method: 'GET',
contentType: 'application/json',
});
response1.done(function(response1) {
test("response1", response1);
})
}
function secondResponse() {
const response2 = $.ajax({
url: 'https://cors-anywhere.herokuapp.com/https://official-joke-api.appspot.com/random_joke',
method: 'GET',
contentType: 'application/json',
});
response2.done(function(response2) {
test("response2", response2);
})
}
var responses = [];
firstResponse();
secondResponse();
function test(index, data) {
responses[index] = data;
if (Object.keys(responses).length === 2) processResponses();
}
function processResponses() {
console.log(responses);
}
There are various more advanced way to handle it, like using async/await or something, but this should get your work done without much modification to your existing code.
UPDATE: for the async/await way which is my preferred way of doing things nowadays:
(async () => {
const response1 = await $.ajax({
url: 'https://cors-anywhere.herokuapp.com/http://api.icndb.com/jokes/random',
method: 'GET',
contentType: 'application/json',
});
const response2 = await $.ajax({
url: 'https://cors-anywhere.herokuapp.com/https://official-joke-api.appspot.com/random_joke',
method: 'GET',
contentType: 'application/json',
});
console.log(response1);
console.log(response2);
})();
I'm trying to get JSON object from axios
'use strict'
async function getData() {
try {
var ip = location.host;
await axios({
url: http() + ip + '/getData',
method: 'POST',
timeout: 8000,
headers: {
'Content-Type': 'application/json',
}
}).then(function (res) {
console.dir(res); // we are good here, the res has the JSON data
return res;
}).catch(function (err) {
console.error(err);
})
}
catch (err) {
console.error(err);
}
}
Now I need to fetch the res
let dataObj;
getData().then(function (result) {
console.dir(result); // Ooops, the result is undefined
dataObj = result;
});
The code is blocking and waits for the result, but I'm getting undefined instead of object
This seems to be one of those cases where async/await doesn't buy you much. You still need to return a result from the async function, which will return a promise to the caller. You can do that with something like:
async function getData() {
try {
let res = await axios({
url: 'https://jsonplaceholder.typicode.com/posts/1',
method: 'get',
timeout: 8000,
headers: {
'Content-Type': 'application/json',
}
})
if(res.status == 200){
// test for status you want, etc
console.log(res.status)
}
// Don't forget to return something
return res.data
}
catch (err) {
console.error(err);
}
}
getData()
.then(res => console.log(res))
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
But in this example, since you don't need to do much in the actual function with the result, you're probably better off just returning axios's promise:
function getDataPromise() {
return axios({
url: 'https://jsonplaceholder.typicode.com/posts/1',
method: 'get',
timeout: 8000,
headers: {
'Content-Type': 'application/json',
}
})
.then(res => res.data)
.catch (err => console.error(err))
}
getDataPromise()
.then(res => console.log(res))
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
It is not what you would like to hear but
Async/Wait works on the principle "Whatever Happens in Vegas - Stays in Vegas". It means you could not pass benefits of using blocking IO calls outside of async block.
If you want to use async/await to create some kind of blocking IO call it would not work unless a block caller is also inside an async function what is not normally the case.
async/wait is only good if you want to have a long chain of IO calls but entire chain still MUST be non-blocking. Individual calls inside chain might be blocking but full chain not.
Example
async fn(url) { //this is a non blocking function
let res = await axios.get("http://jsonservice1"); //blocking but only inside this function
let res2 = await axios.get(url+'?s='+res.data);//res.data is resolved already
return res2; //this how it returns results but it will not be resolved until .then is called what is effectively a callback
}
fn("google.com").then(R=>console.log('sorry I am not blocking '+R.data));
Coming from ajax, I prefer modular approach. Data to be sent, function on success and function on fail are separate from function using axios. Bellow sample code fetch user email against user name form node.js and mysql at the backend.
HTML: <button onclick=" testaxios();">TestAxios</button>
JS in browser:
var data = {
username: "myusername"
}
async function testaxios() {
try {
let res = await axios({
method: 'POST',
data: data,
url: '/testmysql',
});
if (res.status == 200) {
success(res);
};
}
catch (error) {
fail(error);
};
}
function success(res) {
console.log(res.data[0][0].email);
}
function fail(error) {
console.log(error);
}
JS in nodeJS at backend:
app.post("/testmysql", async function (req, res) {
try {
let usrname = req.body.username;
let em = await pool.query("SELECT email FROM users WHERE username = ?", usrname);
res.send(em);
} catch (err) {
console.log(err);
} });
I have to use the SP.RequestExecutor.js library. The problem is I need to run the async function in sync behavior. After deep search I found await and async methods but they are not compatible with Internet Explorer(IE>9). How I can make convert the async functions to sync and be compatible on IE>9 and Chrome?
function executorRun() {
console.log('end2');
var executor = new SP.RequestExecutor('path');
var result=[];
executor.executeAsync({
url: 'URL',
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
},
data: JSON.stringify(requestData),
success: function (data) {
console.log('end3')
console.log(data);//Debug statement
//Handle data and store in result
},
error: function (error) {
console.log(error);
}
});
return result;
}
async function test () {
console.log('end1');
const data = await executorRun();
console.log('end4');
}
test();
I need the output ass follows:
end1
end2
end3
end4.
The above code is running in chrome but on IE refuse the await and async.
In order for await to work, executorRun needs to return a Promise.
function executorRun() {
console.log('end2');
return new Promise(function (resolve, reject) {
var executor = new SP.RequestExecutor('path');
executor.executeAsync({
url: 'URL',
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
},
data: JSON.stringify(requestData),
success: function (data) {
console.log('end3');
console.log(data);//Debug statement
//Handle data and store in result
resolve(data);
},
error: function (error) {
reject(error);
console.log(error);
}
});
});
}
async function test () {
console.log('end1');
const data = await executorRun();
console.log('end4');
}
test();
To use async/await in IE9, you coudl transpile your code with Babel.
You could also just use the Promise directly without the syntactic sugar of async/await:
function test () {
console.log('end1');
executorRun().then(function (data) {
console.log('end4');
});
}
test();
IE doesn't support Promises natively, but they can easily be pollyfilled with any of the many Promise libraries out there.
If you don't want to use Promises, you could always just modify excecutorRun to accept a callback:
function executorRun(callback) {
console.log('end2');
var executor = new SP.RequestExecutor('path');
executor.executeAsync({
url: 'URL',
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
},
data: JSON.stringify(requestData),
success: function (data) {
console.log('end3');
console.log(data);//Debug statement
//Handle data and store in result
callback(data);
},
error: function (error) {
console.log(error);
}
});
}
function test () {
console.log('end1');
executorRun(function (data) {
console.log('end4');
console.log(data);
});
}
test();