I hope someone can help me out with my issue to get back the reject value out of this functions:
(async () => {
await queue.add(() => startCompare(orgpath, dpath, xray));
console.log('done compare ' + entry);
})();
This call the function:
async function startCompare(orgFile, compFile, xFile)
{
let gstderr;
return new Promise((resolve, reject) => {
spawn('compare', [orgFile, compFile, '-metric', 'AE', 'null:'])
.progress(function (childProcess) {
childProcess.stdout.on('data', function (data) {
console.log('[spawn] stdout: ', data.toString());
});
childProcess.stderr.on('data', function (data) {
gstderr = data.toString();
console.log('[spawn] stderr: ', data.toString());
});
}).then(res => {
resolve(true);
}).catch(error => {
resolve(gstderr);
});
});
}
My goal is how to get back gstderr value when rejected. Maybe the arrow function is the wrong way? I want to print out the value at: console.log('done compare ' + entry + xxxxx); where xxxxx is the rejected value.
You can catch the rejected value of a promise with async/await by using try/catch like so:
(async () => {
try {
// if it gets resolved lands here
const result = await startCompare(...args)
console.log(result) // should be true
} catch(error) {
// if it gets rejected it lands here
console.log(error) // should be the gstderr
}
})()
Hope it helps!
export const canLogin = createAsyncThunk("AUTH/login",
async (loginData ,{ rejectWithValue })=> {
try{
const response=await axios.post(AuthConfig.API_URL + AuthConfig.LOGIN_URI, loginData)
return response
}
catch(error){
if (!error.response || !error.message)
throw error
return rejectWithValue(getErrorMessage(error))
}
}
);
export function getErrorMessage(error) {
return (
error?.response?.data?.message ||
error?.response?.data.error ||
error?.response?.data ||
error?.message ||
error.toString()
);
}
Related
Hi guys, I'm newbie in node.js. I have function, that leads the dialogue with user in console. In newSwagger function I call the bumpDiff function, that shows changes between 2 files.
async function bumpDiff = () => {
exec('bump diff swagger.json newSwagger.json', (err, output) => {
// once the command has completed, the callback function is called
if (err) {
// log and return if we encounter an error
console.error("could not execute command: ", err)
return
}
// log the output received from the command
console.log("Output: \n", output)
})
};
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const question = (str) => new Promise(resolve => rl.question(str, resolve));
const steps = {
start: async () => {
return steps.changeSwagger();
},
changeSwagger: async () => {
const addSwagger = await request();
console.log('success');
const changeSwagger = await question("Would you like to check changes in swagger? Please type yes/no: ");
if (changeSwagger === 'yes') { return steps.newSwagger(); }
if (changeSwagger === 'no') { return steps.oldSwagger(); }
return steps.end();
},
newSwagger: async () => {
console.log('showing changes');
const diff = await bumpDiff();
const ask = await question('Would you like to change swagger? Please type yes/no: ');
if (ask === 'yes') { return steps.changing(); }
if (ask === 'no') { return steps.end(); }
},
changing: async () => {
const rebuildSwagger = await SwaggerNew();
console.log('swagger changed successfully');
return steps.end();
},
oldSwagger: async () => {
console.log('No worries, have a nice day');
return steps.end();
},
end: async () => {
rl.close();
},
};
steps.start();
The problems is: when bumpDiff is starting, next readline
'Would you like to change swagger? Please type yes/no: '
come faster, then changes appeares. I guess I'm missing something about promises, can you help me find the mistake please.
P.S. all other functions, like 'request' and 'SwaggerNew' are async.
You are mixing two "styles" the callback approach in the "exec" function and you are trying to await that bumpDiff that is not returning a Promise (async/await approach), take a look to utils.Promisify helper function.
From NodeJS docs:
const util = require('node:util');
const exec = util.promisify(require('node:child_process').exec);
async function lsExample() {
const { stdout, stderr } = await exec('ls');
console.log('stdout:', stdout);
console.error('stderr:', stderr);
}
lsExample();
You need to turn the callback style exec call into a promise so that await bumpDiff() can work properly.
async function bumpDiff = () => {
return new Promise((resolve, reject) => {
exec('bump diff swagger.json newSwagger.json', (err, output) => {
if (err) {
console.error("could not execute command: ", err)
reject(err)
} else {
console.log("Output: \n", output)
resolve(output)
}
})
})
};
My action in the background is to access the site and take information from there, the problem is that the code continues before the information is received.
Attached is a code that shows the problem:
background.js :
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
fetch(request.input, request.init).then(function(response) {
return response.text().then(function(text) {
sendResponse([{
body: text,
status: response.status,
statusText: response.statusText,
}, null]);
});
}, function(error) {
sendResponse([null, error]);
});
return true;
});
actions.js : after editing
const validateWord = async word => {
const input = "https://milog.co.il/" + word;
await new Promise(resolve => {
chrome.runtime.sendMessage({ input }, messageResponse => {
const [response, error] = messageResponse;
const parser = new DOMParser();
const html = parser.parseFromString(response.body, 'text/html');
const element = html.querySelector('.sr_e_txt');
console.log("aaa")
resolve(element?.innerText !== '');
});
});
};
validateWord("word")
.then(data => console.log(data))
.catch(reason => console.log(reason.message))
it prints aaa -> bbb -> word..
I want the "word" printed first and "aaa" wait for it to finish.
Thank you.
you can't use both a callback in a chrome method and await on the returned value because when a callback is used the method won't return a Promise.
bug in Chrome before 99: sendMessage doesn't return a Promise so you can't await it.
Fixed in Chrome 99.
So, in earlier versions of Chrome you can promisify the API:
promisifyApi(chrome.runtime, 'sendMessage');
(async () => {
const res = await chrome.runtime.sendMessage({ input });
console.log(res);
})();
function promisifyApi(thisArg, name) {
const fn = thisArg[name];
const localStack = new Error('Before calling ' + name);
thisArg[name] = (...args) => new Promise((resolve, reject) => {
fn(...args, result => {
let err = chrome.runtime.lastError;
if (err) {
err = new Error(err.message);
err.stack += '\n' + localStack.stack;
reject(err);
} else {
resolve(result);
}
});
});
}
...or use a callback:
chrome.runtime.sendMessage({ input }, res => {
// process `res` here
});
I am unable to get the value of the response outside the callback code. It returns undefined outside whereas in the callback it is giving proper result.
function doCall(urlString, callback) {
request.get(
urlString,
null,
null,
(err, data, result) => {
var statusCode = result.statusCode;
return callback(data);
}
);
}
const apiResponse = doCall(urlString, function(response) {
console.log('***************************' + response); //Prints correct result
return JSON.parse(response);
});
console.log('+++++++++++++++++++++++++' + apiResponse); //Prints undefined
function doCall(urlString) {
return new Promise((resolve, reject) => {
request.get(
urlString,
null,
null,
(err, data, result) => {
if (error) reject(error);
var statusCode = result.statusCode;
resolve(data);
});
});
}
async function myBackEndLogic() {
try {
const result = await doCall(urlString);
console.log(result);
//return JSON.parse(result) if you want
} catch (error) {
console.error('ERROR:');
console.error(error);
}
}
myBackEndLogic();
Read this for more explanations
If you want synchronous looking code, wrap everything in an async function:
(async (){
async function doCall(urlString, callback) {
return await request.get(urlString, null, null); // or store in a variable and return modified response
}
const apiResponse= await doCall(urlString, (response) => {
console.log('response', response);
return JSON.parse(response);
});
console.log('apiResponse', apiResponse);
})()
How can I use the answer of a promise outside of. Then what should I do?
arreglo.forEach((item) => {
if (item.tipoCampo == 3) {
self.campoSelects(item.tablaCampo)
.then(resp => {
console.log(resp)
})
.catch(e => console.log(e))
}
});
console.log (resp) inside the .then () knows it and prints correctly, but when I want to know resp out of the forEach to use below, it says undefined
Thanks.
arreglo.forEach((item) => {
if (item.tipoCampo == 3) {
self.campoSelects(item.tablaCampo)
.then(resp => {
logMyData(resp);
})
.catch(e => console.log(e))
}
});
logMyData=(x)=>{
console.log(x);
}
This is just as simple as adding a helper function which executes inside your .then
Guessing that you want to be able to access the value within the forloop. Since self.campoSelects is a promise we can use async await.
// Call campo selects
function getCampoSelects(_self, tablaCampo) {
return new Promise(async (resolve, reject) => {
let campoData;
try {
campoData = await _self.campoSelects(tablaCampo);
} catch (err) {
reject(err);
}
resolve(campoData);
});
}
function happyLittleFunc() {
const arreglo = [];
arreglo.forEach(async (item) => {
if (item.tipoCampo === 3) {
let campoSelect;
// Unsure if you are setting self somewhere but it can be passed in here.
try {
campoSelect = await getCampoSelects(self, item.tipoCampo);
} catch (err) {
console.log(err);
return;
}
console.log(campoSelect);
}
});
}
happyLittleFunc();
I have made a function in my angular2+ component and the output comes first and the function runs later and hence the appropriate output which i want comes later. The function passes a variable parameter along with the http request to the back-end NodeJS. And returns the result. I want to find its length which i am able to retrieve. However, i want to call this parameter more than once by passing multiple parameters. So i defined it as Asynchronous function. The code is as -
app.component.ts
// Function 1
getNodesCount() {
console.log("INSIDE getNodesCount()")
if (this.selectedAPIName.length == 1) {
this.nodesObjQ1 = {
'relationObj': this.menuItem,
'nodeValue1': this.selectedAPIName[0]
}
this.callFunctionCount(this.nodesObjQ1).then((rs: any[])
=> {
this.nodesObjL1 = rs;
});
console.log("this.nodesObjL1 =", this.nodesObjL1)
}
}
//Function 2
async callFunctionCount(trueNodesObject) {
console.log("nodesObj =", trueNodesObject);
await new Promise(next => {
this.http.get("http://localhost:3003/seekExtraction/nodesObj/" +
JSON.stringify(trueNodesObject))
.map(Response => Response)
.catch((err) => {
console.log("err =", err)
return Observable.throw(err);
})
.subscribe((res: Response) => {
console.log("XXXXXXXXXXXX Response on /seekExtraction",
res);
this.nodesInfo = res;
this.nodesLength = this.nodesInfo.records.length
next()
})
});
console.log("return this.nodesLength =", this.nodesLength)
return this.nodesLength;
}
Major Outputs -
this.nodesObjL1 = undefined
return this.nodesLength = 2
Please help to retrieve this value -
this.nodesObjL1
after this value
this.nodesInfo.records.length= 2
actual minimal example would have helped ensure clean code... but give this a go...
getData = function (trueNodesObject) {
return new promise((resolve, reject) => {
this.http.get("http://localhost:3003/seekExtraction/nodesObj/" +
JSON.stringify(trueNodesObject))
.map(Response => Response)
.catch((err) => {
console.log("err =", err)
return Observable.throw(err);
reject(err);
})
.subscribe((res: Response) => {
console.log("XXXXXXXXXXXX Response on /seekExtraction",
res);
this.nodesInfo = res;
this.nodesLength = this.nodesInfo.records.length
resolve(this.nodesLength);
next()
});
})
}
async function callFunctionCount(trueNodesObject) {
console.log("nodesObj =", trueNodesObject);
const someVal = await getData(trueNodesObject);
console.log("return this.nodesLength =", someVal)
}