I tried without success, to execute my Promise with Sequelize on stored procedure(MSSQL) inside the function, below the code (when I don´t use the Promise, this code runs perfectly, retrieving the json´s data):
function getData(numTravessia) {
return new Promise((resolve, reject) => {
return connection.query(
'EXEC [dbo].[SP_RECUPERAINFOTRAVESSIA] #ID=:param1',
{
replacements: {
param1: numTravessia,
},
type: QueryTypes.SELECT
},
(error, meta, body) => {
if (body != undefined) {
resolve(body.toString());
} else {
reject(error);
}
})
});
}
async function getInfoTravessia(numTravessia) {
try {
var r = await getData(numTravessia);
return JSON.parse(r);;
} catch (error) {
console.log(error);
}
}
app.listen(8000, () => {
console.log("aplicativo em execução");
getInfoTravessia(1955).then((result) => {
console.log(result);
}).catch((e) => {
console.log(e);
})
});
Below, follow the code snippet that I don´t use the Promise and it´s working:
connection.query(
'EXEC [dbo].[SP_RECUPERAINFOTRAVESSIA] #ID=:param1',
{
replacements: {
param1: 1955,
},
type: QueryTypes.SELECT
}).then((result) => {
// RETORNA UM STRING
var obj = result[0];
res.send(obj);
// return obj;
}).catch((e) => {
console.log('error', e);
});
Please, anyone can help me?
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 months ago.
This post was edited and submitted for review 9 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I have tried different ways to send data in arrays but it shows null. I am sure this is because the response fires before the actual response return. Well, this is my guess! I may be wrong.. I want to know the best practice to do this?
My expected result in the payload:
data: {
allCountries: [{TotalCountries: 12}]
allStates: [{StateId: "15327", STR: "Form",…}, {StateId: "15326", STR: "Form",…},…]
AllCities: [,…]
AllCust: {Id: "1825",…}
}
Now, in nodejs controller, I have 4 functions
exports.getAllDetails = async (req, res) => {
if (!req.query.clientId) {
return res.status(406).send({
success: false,
message: "ID is required"
})
}
let id = req.query['custId'];
let allCountries= await getAllCountries(req, res, id)
// let allStates= this.getStates(req, res, id);
// let allCities= this.getAllCities(req, res, id);
// let custDetails= this.getCustDetails(req, res, id);
return res.send({
success: true,
data:
[allCountries]
[allStates],
[AllCities],
[AllCust]
})
}
Now I have created separate functions for all. i.e.
async function getAllCountries(req, res, id) {
let allCountries;
allCountries= `SELECT query..`
connection.query(allCountries, (err, result) => {
if (result) {
if (result.length > 0) {
return result;
} else {
res.status(204).send({
success: false,
message: `No data found.`,
});
}
}
});
}
I am getting null array in result?
Can anyone tell me the best way to do this?
Because you're trying to return data from callback function :
async function getAllCountries(req, res, id) {
let allCountries;
allCountries= `SELECT query..`
connection.query(allCountries, (err, result) => {
if (result) {
if (result.length > 0) {
return result; // this won't work because it is inside callback function.
} else {
res.status(204).send({
success: false,
message: `No data found.`,
});
}
}
});
}
you need to return promise object :
async function getAllCountries(id) {
let allCountries;
allCountries= `SELECT query..`
return new Promise((resolve) => {
connection.query(allCountries, (err, result) => {
if (result) {
if (result.length > 0) {
resolve(result);
} else {
resolve(null);
}
}
});
});
}
also where you're using this function :
let allCountries= await getAllCountries(id);
if (allCountries == null) {
return res.status(204).send({
success: false,
message: `No data found.`,
});
}
I Will recommend you start using try/catch to handle errors instead of all your function passing the param req/res, whit this solution your code will be more readable.
function getAllCountries(req, res, id) {
return new Promise((res, rej) => {
let allCountries;
allCountries = `SELECT query..`;
connection.query(allCountries, (err, result) => {
if (err) {
rej(err);
}
if (result.length === 0) {
rej({
success: false,
message: `No data found.`,
});
}
res(result);
});
});
}
in your main function:
exports.getAllDetails = async (req, res) => {
if (!req.query.clientId) {
return res.status(406).send({
success: false,
message: 'ID is required',
});
}
try {
let id = req.query['custId'];
let allCountries= await getAllCountries(id)
...
return res.send({
success: true,
data: {
allCountries, //as you want this as array wrap the allCountries as [allCountries]
...
}
})
} catch (err) {
return res.status(400).send(err);
}
};
I'm new to NodeJS so please apologize if below code is not up-to the standard. I would like to access isSuccess value outside of this function stepfunctions.listExecutions
I tried below code but I'm getting the value is undefined not getting the expected output. I did some internet search and came to know in NodeJS we can't set the value which is defined in globally but I've use case and I'm pretty sure this is a common case for others too - where I would like to access this isSuccess value after my execution.
const AWS = require('aws-sdk');
const stepfunctions = new AWS.StepFunctions({
region: process.env.AWS_REGION
});
var params = {
stateMachineArn: 'arn:aws:states:us-west-1:121:stateMachine:test',
maxResults: '2',
nextToken: null,
statusFilter: 'SUCCEEDED'
};
var isSuccess
stepfunctions.listExecutions(params, function (err, data) {
if (err) console.log(err, err.stack);
else
data.executions.forEach(function (result) {
let params = {
executionArn: result.executionArn
};
stepfunctions.describeExecution(params, function (err, data) {
if (err) console.log(err, err.stack);
else {
isSuccess = 'true'
}
});
});
console.log('isSuccess: ' +isSuccess)
});
Expected output:
isSuccess: true
But I'm getting
isSuccess: undefined
Could you please help me to resolve this issue. Appreciated your help and support on this.
This is how you can wrap it on promise
let isSuccess;
const listExecute = function(params) {
return new Promise((resolve, reject) => {
stepfunctions.listExecutions(params, function (err, data) {
if (err) reject(err);
else
data.executions.forEach(function (result) {
let params = {
executionArn: result.executionArn
};
stepfunctions.describeExecution(params, function (err, data) {
if (err) reject(err);
else {
resolve(true)
}
});
});
});
})
}
async function getOutout(params) {
try {
isSuccess = await listExecute(params);
console.log(isSuccess, 'Output')
} catch(e) {
console.log(e)
}
}
getOutout(params)
Also you can export the listExecute so that you can use this function outside of this file.
module.exports = {listExecute}
I'm using ipcRenderer.send() to send an array of objects back to ipcMain. Here's my code:
const loadData = async () => {
let promises = [];
['stocks', 'crypto', 'vehicles', 'property'].forEach(item => {
promises.push(getTableData(item))
})
let data = {}
await Promise.allSettled(promises).then(results => {
for (let i in results) {
var result = results[i]
if (result.status === 'fulfilled') {
console.log(result.value.type)
// result.value.data will be an array of objects
console.log(result.value.data)
data[result.value.type] = result.value.data
} else {
console.error(result)
}
}
}).finally(_ => {
console.log(data)
ipcRenderer.send('asynchronous-message', data)
})
}
When result.value.data is printed via console.log, it shows the correct data (comes from an SQL query):
{ stocks: [{id: 1, ticker: "BRK.B", action: "ADD", price: 173.97, shares: 6}, ...], ...}
However, when it gets printed in ipcMain.on('asynchronous-message', ...), it prints empty arrays for the values:
{ stocks: [], crypto: [], vehicles: [], property: [] }
How would I send an IPC message with a complex object? Is it not being serialized correctly?
For reference, here is my ipcMain.on('asynchronous-message', ...) code:
ipcMain.on('asynchronous-message', async (event, data) => {
console.log(data)
})
In addition, here is getTableData():
const getTableData = (table) => {
let toReturn = {
type: `${table}`,
data: []
}
return new Promise((resolve, reject) => {
try {
db.run(`PRAGMA table_info('${table}');`, err => {
if (err) {
reject(err)
} else {
db.each(`SELECT * FROM ${table}`, (err, row) => {
if (err) {
reject(err)
} else {
toReturn.data.push(row)
}
})
resolve(toReturn)
}
})
} catch (e) {
reject(e)
}
})
}
Where each row is an object that looks like:
{id: 1, ticker: "AAPL", action: "ADD", price: 100.0,
shares: 10, datetime: "2020-05-14 23:24:50", platform: ""}
With #Estradiaz's help, I realized that the promise was being resolved before the SQL query had been processed. To fix this, I switched from using db.each() to db.all(). Here is my updated getTableData():
const getTableData = (table) => {
let toReturn = {
type: `${table}`,
data: []
}
return new Promise((resolve, reject) => {
try {
DB.run(`PRAGMA table_info('${table}');`, err => {
if (err) {
console.error(err)
reject(err)
} else {
DB.all(`SELECT * FROM ${table}`, (err, rows) => {
if (err) {
console.error(err)
reject(err)
} else {
toReturn.data = rows
resolve(toReturn)
}
})
}
})
} catch (e) {
console.error(e)
reject(e)
}
})
}
i was trying to get the list of some datas from mysql using hapi.js. But I'm getting this error
Error: method did not return a value, a promise, or throw an error
but i can see those data's in my console.
[ RowDataPacket { id: 1, code: 'test', description: 'bla', format: '12' },
RowDataPacket { id: 2, code: 'test2', description: 'test', format: '15' } ]
this is my handler code:
exports.getInfo = async (request, h) => {
try {
pool.query(`SELECT * FROM test`, (err, result) => {
if (err) throw err;
console.log(result);
return h.response(result);
});
} catch (e) {
if (e.response) {
switch (e.response.status) {
case 404: return Boom.notFound();
default: return Boom.failedDependency();
}
} else {
return Boom.failedDependency();
}
}
};
This is problem of promise, i guess mysql doesn't return any promise. How can I solve this issue?
You are already using async operator that means you can utilize the async/await approach in your code.
I assume that your pool.query method is returning a promise, so your code could be like this.
exports.getInfo = async (request, h) => {
try {
const result = await pool.query(`SELECT * FROM test`);
return result;
} catch (e) {
if (e.response) {
switch (e.response.status) {
case 404:
return Boom.notFound();
default:
return Boom.failedDependency();
}
} else {
return Boom.failedDependency();
}
}
};
If not, then you can convert your pool.query method to a Promise.
const QueryResult = (query) => {
return new Promise((resolve, reject) => {
pool.query(`SELECT * FROM test`, (err, result) => {
if (err) return reject(err);
return resolve(result)
});
})
}
exports.getInfo = async (request, h) => {
try {
const result = await QueryResult(`SELECT * FROM test`);
return result;
} catch (e) {
if (e.response) {
switch (e.response.status) {
case 404:
return Boom.notFound();
default:
return Boom.failedDependency();
}
} else {
return Boom.failedDependency();
}
}
};
I am using Slack API and I want to test does it work fine with response status code. Here is sending function :
sendMsg(msg) {
return this.slack.webhook({text: msg}, (err, res) => {
if (err) {
throw err;
}
console.log(res.statusCode) // = 200
return res.statusCode;
});
}
And my test:
it('Checks connection with Slack', (() => {
let slack = new Slack();
let res = slack.sendMsg('test');
expect(res).to.equal(200);
}));
But ofc. it's giving me request object to slack. I want to wait for response object from slack API. Thanks in advance.
It looks like slack.webhook takes in a callback, which is how you retrieve the status. The problem is that the caller of sendMsg has no way of getting that status.
One way to solve this is to have sendMsg take in a callback:
sendMsg(msg, onStatusReceived) {
this.slack.webhook({text: msg}, (err, res) => {
if (err) {
throw err;
}
console.log(res.statusCode) // = 200
onStatusReceived(res.statusCode);
});
}
Then in your test, use done to end the test when the callback is invoked:
it('Checks connection with Slack', (done) => {
let slack = new Slack();
slack.sendMsg('message', status => {
expect(status).to.equal(200);
done();
});
});
Another way is to have sendMsg wrap slack.webhook in a promise, so the caller can do sendMsg().then(...).
one of the ways I handled a returning callback to test is as follows:
it('receives successful response', async () => {
nock('https://localhost')
.persist()
.log(console.log)
.post(‘/getData’, (unitData, callback) => {
return true;
})
.delayBody(1000)
.reply(200, {statusCode: 'Some Status'});
const getSomeData = await getResponse(unitData, function callBack(unitData, error, data){
expect(data.statusCode).to.be.equal(200);
}) })
getResponse Function (returning callback):
getResponse(unitData, function callBack(unitData, error, data){
try {
return request.post(unitData, function (err, resp) {
if (!err && resp.statusCode === 200) {
if (resp.body.error) {
return callback(obj, JSON.stringify(resp.body.error), null);
}
return callback(obj, null, resp);
} else {
if (err == null) {
err = { statusCode: resp.statusCode, error: 'Error occured.' };
}
return callback(obj, err, null);
}
});
} catch (err) {
return callback(obj, err, null);
}
}