How do I use aysnc/await in this superagent call? - javascript

This is a superagent call, I have imported request(i.e is exported from my superagent component class)
How do I use async/await in this for "res.resImpVariable".
request
.post(my api call)
.send(params) // an object of parameters that is to be sent to api
.end((err, res) => {
if(!err) {
let impVariable = res.resImpVariable;
} else {
console.log('error present');
}
});

I reformulated my answer. I think I was misinterpreting before. You could wrap the entire sequence into a Promise-returning function that resolves after the response callback:
function callSuperagent() {
return new Promise((resolve, reject) => {
return request
.post(my api call)
.send(params) // an object of parameters that is to be sent to api
.end((err, res) => {
if(!err) {
console.log('get response', res);
// uncomment this to see the catch block work
// reject('Bonus error.');
resolve(res);
} else {
console.log('error present', err);
reject(err);
}
});
});
}
Then, you can create an async function and await that:
async function doSomething() {
try {
const res = await callSuperagent();
// uncomment this to see the catch block work
// throw 'Artificial error.';
console.log('res', res);
console.log('and our friend:', res.resImpVariable);
} catch (error) {
throw new Error(`Problem doing something: ${error}.`);
}
}
doSomething();
Or if you don't make doSomething, it would be like this:
callSuperagent()
.then((res) => {
console.log('res', res);
console.log('and our friend:', res.resImpVariable);
})
.catch((err) => {
console.log('err', err);
})

Related

Returning undefined result after awaiting function

I am trying to get the result back from function where the result is in the callback. However the result always come back as undefined even though I set it to be the res. Can someone explain why this does not work?
function getData(id, callback) {
return dataModel.findOne({ id }).exec((err, res) => {
if (err) return callback(err)
return callback(null, res)
})
}
async function middleware(req.body) {
try {
let result
await getData(req.body, (err, res) => {
if (err) throw err
result = res
})
await nextFunc(result)... // result is undefined
} catch (err) {
console.log(err)
}
}
You are using callbacks, but in order to make things work with async await you are supposed to use promises
Try
function getData(id, callback) {
return new Promise((resolve, reject) => {
dataModel.findOne({ id }).exec((err, res) => {
if (err) reject(err);
resolve(res);
});
});
}
async function middleware(req.body) {
try {
let result = await getData(req.body);
await nextFunc(result);
} catch (err) {
console.log(err);
}
}

How to handle reject promise error in outer try catch with inner Promise.all?

When an error/rejection occurs in detectingDog or detectingDog, the error is successfully handled by the .catch(error of the Promise.all() but I want the error to be directly handled by the catch (err) of the try structure.
How can I do this ?
PS: I have already tried to get rid of the .catch(error but then the Promise.all() hangs forever
try {
function detectingDog(bufferedData) {
return new Promise((resolve, reject) => {
package.detectDog(bufferedData, function(error, data) {
if (error) {
reject(error);
} else {
return resolve(data);
}
});
});
}
function detectingCat(bufferedData) {
return new Promise((resolve, reject) => {
package.detectCat(bufferedData, function(error, data) {
if (error) {
reject(error);
} else {
return resolve(data);
}
});
});
}
Promise.all([
detectingDog(param1),
detectingCat(param2)
]).then(responseData => {
callback(undefined, responseData);
}).catch(error => {
// (1) I need to pass the error to the outer structure where error handling is done
});
} catch (err) {
console.log(err);
// handing of the inner error (2) here
callback(err);
}
Thanks!
...but I want the error to be directly handled by the catch (err) of the try structure.
You can't do that in a non-async function, because control has already left the try/catch by the time that rejection occurs, which is after whatever function this code is in (if any) has returned.
In an async function, you can use await on a promise, which will make a rejection throw, so it would go to your try/catch. So you could do the following, but keep reading because it's fairly odd:
// In an `async` function
try {
function detectingDog(bufferedData) {
return new Promise((resolve, reject) => {
package.detectDog(bufferedData, function(error, data) {
if (error) {
reject(error);
} else {
return resolve(data);
}
});
});
}
function detectingCat(bufferedData) {
return new Promise((resolve, reject) => {
package.detectCat(bufferedData, function(error, data) {
if (error) {
reject(error);
} else {
return resolve(data);
}
});
});
}
const responseData = await Promise.all([
detectingDog(param1),
detectingCat(param2)
]);
callback(responseData);
} catch (err) {
console.log(err);
callback(err);
}
...but it doesn't make a lot of sense to go to the trouble of converting callback APIs to promises if you're just going to provide a callback-based API to your caller. Just return a promise. That makes the whole try/catch disappear:
// No need for these to be nested
function detectingDog(bufferedData) {
return new Promise((resolve, reject) => {
package.detectDog(bufferedData, function(error, data) {
if (error) {
reject(error);
} else {
resolve(data); // No need for `return`
}
});
});
}
function detectingCat(bufferedData) {
return new Promise((resolve, reject) => {
package.detectCat(bufferedData, function(error, data) {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
}
function example(param1, param2) {
return Promise.all([
detectingDog(param1),
detectingCat(param2)
]);
}
You have two options here.
If you really need the try/catch block you will need to run your code in an async function, leveraging the fact that awaiting a rejected Promise will throw an error in this context:
(async function () { // you might not need the immediately invoking function wrapper depending on your context
try {
function one(bufferedData) {
// return a promise
}
function two(bufferedData) {
// return a Promise
}
const responseData = await Promise.all([
one(param1),
two(param2)
])
callback(undefined, responseData)
} catch (err) {
console.log(err);
// handing of the inner error (2) here
callback(err)
}
})()
Alternatively, you can also just handle the error in the catch block of your Promise chain:
function one(bufferedData) {
// return a promise
}
function two(bufferedData) {
// return a Promise
}
Promise.all([
one(param1),
two(param2)
])
.then((responseData) => {
callback(undefined, responseData)
})
.catch((err) => {
console.log(err);
// handing of the inner error (2) here
callback(err)
})

What is the syntax to using await and async in asynchronous functions using nodejs?

I am trying to create a basic API in nodejs to perform CRUD actions on a database.
I do not understand why the result is undefined
exports.getPlaylist = async function (req, res) {
console.log('Recieved getPlaylist request');
result = await connection.executeQuery('SELECT * from Users');
res.status(200).send(result);
console.log(result); // Logs undefined
};
This is the function that gets called and gets the data from the database:
async executeQuery(query) {
connection.query(query, function (err, result) {
if (err) {
console.log('Error executing query: ' + err);
}
console.log(result); // logs correct data
return result;
});
}
You need to "promisify" your callback. (see require('utils').promisify ) for a shorthand for applying to functions that follow node.js callback style (function(err,result){}).
executeQuery(query) {
return new Promise((res, rej) => {
connection.query(query, function (err, result) {
if (err) {
console.log('Error executing query: ' + err);
rej(err)
} else {
console.log(result); // logs correct data
res(result);
}
});
});
}
Now inside an async function you can await executeQuery(query)
The execute is not a promise base function, you cannot use await on a callback function.
change the execute function to promise base
Example:
executeQuery(query) {
return new Promise( (resolve, reject) => {
connection.query(query, function (err, result) {
if (err) {
console.log('Error executing query: ' + err);
reject('Error executing query: ' + err);
}
console.log(result); // logs correct data
resolve(result);
});
});
}
Add try catch in your calling function
exports.getPlaylist = async function (req, res) {
console.log('Recieved getPlaylist request');
try{
result = await connection.executeQuery('SELECT * from Users');
res.status(200).send(result);
console.log(result); // Logs undefined
} catch(error) {
console.log(error)
}
};

How is this possible? Things should get printed but they dont

I don't understand how the console.logs not getting printed.
import { GenericRepository, getGenericRepository } from '../src/database/repository/GenericRepository';
import { start, stop } from '../src/index';
import request from 'request';
const baseUrl = 'http://localhost:3200/';
const getTable = async (tableName: string) => {
const data = {
'tableName': 'tableName'
};
const header = {
url: baseUrl + 'table',
method: 'POST',
json: true
};
console.log('hello');
request.post({
url: 'http://localhost:3200/getTable',
body: data,
json: true
}, (error, response, body) => {
console.log('getting angry');
if (error) {
console.error('error: ', error);
} else {
console.log(response);
}
});
await new Promise((resolve, reject) => {
request.post({
url: 'http://localhost:3200/getTable',
json: data
}, (error, response, body) => {
console.log('getting angry');
if (error) {
console.error('error: ', error);
reject(error);
} else {
console.log(response);
resolve('response' + response);
}
});
})
}
describe('A suite', function () {
beforeAll(async done => {
// await start()f.catch(error => { console.log(error); });
done();
});
afterAll(() => {
console.log('afterall')
});
it('contains spec with an expectation', async done => {
console.log('spec executed')
getTable('supply').then(result => {
console.log('result: ', result)
}).catch(error => {
console.log('error', error);
});
console.log('after getTable')
done();
// expect(table.length).toBeGreaterThan(0);
});
});
Neither of these are getting printed:
console.log('getting angry');
console.error('error: ', error);
console.log(response);
console.log('result: ', result);
console.log('result: ', result);
console.log(response);
what actually gets printed is:
Started
spec executed
hello
after getTable
.afterall
Please help me understand what's going on!.
I tested it with postman the server is working properly.
I would expect that the request would return the same result as the postman does.
it('contains spec with an expectation', async done => {
console.log('spec executed')
getTable('supply').then(result => {
console.log('result: ', result)
}).catch(error => {
console.log('error', error);
});
console.log('after getTable')
done();
// expect(table.length).toBeGreaterThan(0);
});
This code says to synchronously do all of the following: Call getTable, which returns a promise. Then schedule some stuff to be done when (if) that promise resolves. Then call done(), thus ending the test. Since the test has been ended, the async stuff in getTable doesn't happen, nor do the .then callbacks.
Instead, you need to wait until getTable's promise is done resolving before you finish the test. Also, since you're already in an async function, you don't need to be using .then callbacks, and don't need to use done() since jasmine knows to wait until the async function's promise finishes. For example:
it('contains spec with an expectation', async () => {
console.log('spec executed')
try {
const result = await getTable('supply')
console.log('result: ', result)
} catch (error) {
console.log('error', error);
}
console.log('after getTable')
});
You're almost there, but your call to done() is not in the right place. The test will run, launch the Promise and then immediately notify that it is done() before the promise has chance to resolve or reject.
Try moving the done() to within the then and catch blocks:
it('contains spec with an expectation', async done => {
getTable('supply').then(result => {
console.log('result: ', result)
done()
}).catch(error => {
console.log('error', error)
done.fail(error)
});
});

Express: Resolved Promise going to catch Call

I am trying to send the data from a promise, using Promise chaining the Promise is getting resolved. But the catch call is running not then call
Here is the code from where I am returning the data using Promise:
UserSchema.statics.findByCredentials = function(email, password) {
const User = this;
return User.findOne({
email
}).then((user) => {
if(!user) {
return Promise.reject();
}
try {
return new Promise((reject, resolve) => {
bcrypt.compare(password, user.password, (err, res) => {
// console.log(res);
if(res)
resolve(user);
else
reject("Invalid Credentials");
});
});
}
catch(error) {
Promise.reject(error);
}
});
};
Here is the Promise chain call, where catch call is working not the then call
app.post('/users/login', (req, res) => {
const body = _.pick(req.body, ['email', 'password']);
// console.log(body);
User.findByCredentials(body.email, body.password)
.then((user) => {
}).catch(error => {
error.generateAuthToken().then((token) => {
res.header('x-auth',token).send(error);
});
});
});
Hi tweaked the code, to have another call on the catch.
Could be there any better solution for that.
It's sure that the data is being returned that means, Promise is resolved.

Categories