using await within function of backend api - javascript

I have the code below:
service.js
module.exports = {
getUser
};
async function getUser({ data }) {
return new Promise((resolve, reject) => {
const id = data["id"];
const doc = await db.collection('users').where('id', '==', id).get();
if (!doc.exists) {
resolve('No such document!');
} else {
resolve(doc.data());
}
});
}
controller.js
async function getUser(req, res, next) {
userService.getUser({ data: req.body }).then(function (val) {
res.json(val);
});
}
This throws an error: SyntaxError: await is only valid in async functions and the top level bodies of modules. How can I retrieve the data from the await in an effective manner?

You can use await only inside async function.
function dummy() {
return new Promise((res, rej) => {
setTimeout(() => {
res(20)
}, 300)
})
}
let val = new Promise(async(resolve, reject) => {
let v = await dummy()
resolve(v)
})
val.then(value => console.log(value))

Related

Nodejs multiple axios get requests return a Primise

How to return a Promise from the multiple axios get requests?
I have below code.
async function main() {
const URL_1 = 'abc.com/get1/data1';
const result_1 = await getData(URL_1);
const URL_2 = 'abc.com/get2/data2';
const result_2 = await getData(URL_2);
}
async function getData(dataURI) {
let getURI = dataURI;
const config = {
headers: {
Authorization: `Bearer ${my-token-text}`,
},
};
var finalData = [];
// until we get the next URL keep sending the requests
while (getURI != null) {
try {
const getResult = await axios.get(getURI, config);
if (getResult.status === 200) {
const receivedData = getResult.data.value;
finalData.push(...receivedData);
// check if we have nextLink in the payload
if (Object.prototype.hasOwnProperty.call(getResult.data, 'nextLink')) {
getURI = getResult.data.nextLink;
} else {
getURI = null;
return finalData;
}
}
} catch (err) {
break;
}
}
return null;
}
What I am trying to achieve is:
async function main() {
const URL_1 = 'abc.com/get1/data1';
const result_1 = getData(URL_1);
promisesArray.push(result_1);
const URL_2 = 'abc.com/get2/data2';
const result_2 = getData(URL_2);
promisesArray.push(result_2);
await Promise.allSettled(promisesArray).then((results) => {
console.log('Promise All Done: ', results);
});
}
This why I can perform all the requests in parallel.
But when I update the function getData(dataURI) to return return new Promise then I get error for await axios.
async function getData(dataURI) {
return new Promise((resolve, reject) => {
// Same code as above
});
}
I get error:
SyntaxError: await is only valid in async function
As Promise is not async I cannot await in the Promise.
Have you tried:
return new Promise(async (resolve, reject) => {
// Same code as above
});

Why doesn't promise return from Lambda work while returning stream to handler for uploading to S3?

I want to return a stream from a function for the main Lambda handler to create a pipe. This works:
const { S3Client } = require("#aws-sdk/client-s3")
const { Upload } = require('#aws-sdk/lib-storage')
const stream = require('stream')
const s3Region = 'us-east-1'
const bucketname = "my_bucket"
exports.handler = function (event, context, callback) {
let streamfrom = stream.Readable.from(["four"])
getS3Stream()
.then(streamto => {
stream.pipeline(
streamfrom,
streamto,
() => {
callback(null, { 'statusCode': 200 })
})
})
}
function getS3Stream() {
return new Promise(resolve => {
const pass = new stream.PassThrough()
const upload = new Upload({
client: new S3Client({ region: s3Region }),
params: {
Bucket: bucketname,
Key: "test/test.txt",
Body: pass
}
})
upload.done().then((res, error) => {
if (error) { reject(error) }
console.log("s3 uploaded")
})
resolve(pass)
})
}
But I want the handler function to return a promise instead of using a callback, at which point it no longer works:
exports.handler = async function (event, context) {
return new Promise(resolve => {
let streamfrom = stream.Readable.from(["five5"])
getS3Stream()
.then(streamto => {
stream.pipeline(
streamfrom,
streamto,
() => {
resolve({ 'statusCode': 200 })
})
})
})
}
It returns {"statusCode":200}, but "s3 uploaded" is not printed, and the file does not appear in S3.
Am I misunderstanding something about how to use promises here?
If you want your handler to return a Promise, you have to mark it as async.
I have not found any documentation on this but I believe the runtime caller first checks the handler definition so it know how it should call it.
Something like:
if (handler.constructor.name === 'AsyncFunction') {
result = await handler(event, context)
handleResult(null, result)
} else if (handler.constructor.name === 'Function') {
handler(event, context, handleResult)
} else {}
So, going back to your original code, it can be simply
exports.handler = async function (event, context) {
return new Promise(resolve => {
let streamfrom = stream.Readable.from(["five5"])
getS3Stream()
.then(streamto => {
stream.pipeline(
streamfrom,
streamto,
() => resolve({'statusCode': 200})
)
})
})
}
function getS3Stream() {
return new Promise(resolve => {
const pass = new stream.PassThrough()
const upload = new Upload({
client: new S3Client({region: s3Region}),
params: {
Bucket: bucketname,
Key: "test/test.txt",
Body: pass
}
})
upload.done().then((res, error) => {
if (error) {
reject(error)
}
console.log("s3 uploaded")
resolve(pass)
})
})
}
Inspired by this I came up with a solution that almost meets my qualifications. The function doesn't return just the stream, it also returns the promise. I am still hoping someone will come up with something that works without that crutch.
const { S3Client } = require("#aws-sdk/client-s3")
const { Upload } = require('#aws-sdk/lib-storage')
const stream = require('stream');
const s3Region = 'us-east-1'
const bucketname = "my_bucket"
exports.handler = async function (event, context) {
return new Promise(resolve => {
let streamfrom = stream.Readable.from(["five5"])
getS3Stream()
.then(({streamto, promise})=>{
stream.pipeline(
streamfrom,
streamto,
() => promise.then(()=>resolve({ 'statusCode': 200 }))
)
})
})
}
async function getS3Stream() {
const streamto = new stream.PassThrough()
const s3Client = new S3Client({ region: s3Region })
const upload = new Upload({
client: s3Client,
params: {
Bucket: bucketname,
Key: "test/test.txt",
Body: streamto
}
})
let promise = upload.done()
return({streamto,promise})
}

Issues with async/await

I'm trying to use async/await for a very basic promise, but I'm getting the error: SyntaxError: await is only valid in async function. However, I believe I'm using await for an async function.
function getNumber(mult) {
return new Promise((resolve, reject) => {
resolve(10);
}).then((val) => {
return new Promise((resolve, reject) => {
resolve(val * mult)
//reject("Error");
}).then((val2) => val2);
}).catch((err) => {
return err;
})
}
const calculate = async (x) => await Promise.resolve(getNumber(x))
const val = await calculate(2)
You cannot have the initial function with an await at the top level... just a modification.
function getNumber(mult) {
return new Promise((resolve, reject) => {
resolve(10);
}).then((val) => {
return new Promise((resolve, reject) => {
resolve(val * mult)
//reject("Error");
}).then((val2) => val2);
}).catch((err) => {
return err;
})
}
const calculate = (x) => Promise.resolve(getNumber(x));
const val = calculate(2).then(resp => {
console.log('do something with response: ', resp)
})
To only focus on why you're getting that error, the await in await calculate(2) isn't in an asynchronous function. If you can make it asynchronous function then do that but if not then you can use the .then() function like below:
calculate(2).then(val => {
//Your code here
}

SyntaxError: await is only valid in async function. Unable to Correct it

I am unable to run the following code.
It shows me this error:
SyntaxError: await is only valid in async function
const Prom = async() => {
return new Promise((resolve, reject) => {
let a = 2;
if (a == 2) {
resolve('Its working');
} else {
reject('Its not working');
}
});
};
const final = await Prom();
console.log(final);
You could use IIFE
const Prom = async () => {
return new Promise((resolve, reject) => {
let a = 2
if (a == 2) {
resolve('Its working')
} else {
reject('Its not working')
}
})
}
;(async function() {
const final = await Prom()
console.log(final)
})()
const Prom = async () => {
return new Promise((resolve, reject) => {
let a = 2;
if (a == 2) {
resolve('Its working');
} else {
reject('Its not working');
}
});
};
const final = async () => {
const result = await Prom();
console.log(result);
};
final();
await can only be used inside an async function.
The error here is referring to the final variable. It has to be inside of an async function. Try using the below code.
const prom = new Promise((resolve, reject) => {
let a = 2;
if (a == 2) {
resolve('Its working');
} else {
reject('Its not working');
}
});
(async function() {
const final = await prom;
console.log(final)
})()

nodejs how to use multiple await promises

how can i use multi promise await in my codes ? when i wanna use second await for second promise it throw an error
function ReadJSONFile() {
return new Promise((resolve, reject) => {
fs.readFile('import.json', 'utf-8', (err, data) => {
if (err) reject(err);
resolve(JSON.parse(data));
});
});
}
const Get_Image = async (Path) => {
Child_Process = exec('node get_image.js "'+Path+'",(err,stdout,stderr) =>
return new Promise((resolve,reject) => {
resolve(stdout);
});
}
const Catch = async () => {
let get_json_file = await ReadJSONFile(); // this works perefectly
for(var i=0;i< Object.keys(get_json_file);i++) {
console.log(await Get_Image(get_json_file[i].image_path); //but this throw error
}
}
you didn`t return a promise that is why you got an error
const Get_Image = async (Path) => {
return new Promise((resolve,reject) => {
Child_Process = exec('node get_image.js "'+Path+'",(err,stdout,stderr) =>
resolve(stdout);
});
});
}

Categories

Resources