async await , nodejs readfile and then do other - google-api

I tried to read file through async/await and update the credentials , But i got response HI first and then hello in console.And Credentials also not updated in oauthClient2.
const getFile = async (req, res, next) => {
await fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return null;
console.log("hello")
console.log(JSON.parse(token));
oauth2Client.credentials = JSON.parse(token);
});
console.log("HI")
var service = google.drive({
version: 'v3',
encoding: null
});
console.log(oauth2Client);
await service.files.get({
auth: oauth2Client,
fileId: "1ZR8kkvb2JYVxcUjmlgfBJD2IYnisaiFn",
alt: 'media'
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
responder(res)(null,response);
});
}
Is there a way in which everything should run in a order?
Thank You.

The reason you are experiencing the error you see, is because the method you are running is asynchronous. You should instead use the alternative synchronous version:
let token;
try {
token = fs.readFileSync(TOKEN_PATH, 'utf8');
} catch (err) {
console.error(err)
}
if(!token){ return; }
oauth2Client.credentials = token;
const service = google.drive({
version: 'v3',
encoding: null
});
await service.files.get({
auth: oauth2Client,
fileId: "1ZR8kkvb2JYVxcUjmlgfBJD2IYnisaiFn",
alt: 'media'
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
responder(res)(null,response);
});
Ref: https://nodejs.dev/learn/reading-files-with-nodejs

Related

How to get error from backend with axios?

I'm trying to display an error I recieve in my backend to the user in my JSX frontend file.
This is the initial call from frontend
dispatch(createGoal({ values }))
Goalslice, directly called from JSX:
export const createGoal = createAsyncThunk(
'goals/create',
async (goalData, thunkAPI) => {
try {
const token = thunkAPI.getState().auth.user.token
return await goalService.createGoal(goalData, token)
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString()
return thunkAPI.rejectWithValue(message)
}
}
)
Goalservice, directly called from goalslice:
const createGoal = async (goalData, token) => {
const config = {
headers: {
Authorization: `Bearer ${token}`,
},
}
const response = await axios.post(API_URL, goalData, config)
return response.data
}
Goalcontroller, my backend:
const setGoal = asyncHandler(async (req, res) => {
const goals = await Goal.find({ user: req.user.id })
var count = Object.keys(goals).length
if(count >2){
res.status(400)
throw new Error('Maximum of 3 trackers per user')
}
if (!req.body.values) { //if this isnt there. check if the body is there.
res.status(400) //This is an error
throw new Error('Please add a date field') //this is express error handler
}
console.log(req.body.values.dates)
const goal = await Goal.create({
values: req.body.values.dates, //get from request body
permit: req.body.values.permits,
numpermit: req.body.values.num,
user: req.user.id,
})
res.status(200).json(goal)
})
I want to display this error:
throw new Error('Maximum of 3 trackers per user')
I tried a try/catch method, but I'm very new to this and I feel like i'm missing a very key point in how it all fits together.
This is my custom error handler if it helps:
const errorHandler = (err, req, res, next) => { //overwrite express error handler, next to handle any new req
const statusCode = res.statusCode ? res.statusCode : 500 //500 is server error. conditional
res.status(statusCode)
res.json({
message: err.message,
stack: process.env.NODE_ENV === 'production' ? null : err.stack, //gives additional info if in development mode : is else
})
}
module.exports = { //export for others to use
errorHandler,
}

NextJs - Node - API resolved without sending a response for /api/xxx

I have a nextjs app with a backend api where I am sending an email out.
I have seen a couple of other posts with the same issue, have tried their resolutions and not sure what I am missing.
Any insight is appreciated.
The code in the API is below.
const nodemailer = require('nodemailer');
export default function (req, res) {
const mailData = {
from: 'xxxxx',
to: req.body.email,
subject: 'Message to Full On Consulting',
text: req.body.message,
html: '<div>'+req.body.message+'</div>'
}
sendMail(mailData)
.then((result) => {
console.log('Email sent...', result);
res.status(200).json({ status: 'SUCCESS' })
})
.catch((error) => console.log('Error ... ' + error.message));
}
async function sendMail(mailData) {
try {
let transport = nodemailer.createTransport({
host: "mail.xxxxxxxxxx.com",
port: 587,
secure: false,
auth: {
user: process.env.GMAIL_UID,
pass: process.env.GMAIL_PW
}
});
const result = await transport.sendMail(mailData)
return result;
} catch (error) {
console.log("CATCH ERROR: " + error)
return error;
}`enter code here`
}
I wrapped the sendmail call in a promise and that seems to have worked.
var promise = new Promise( (resolve, reject) => {
let result = transport.sendMail(mailData);
});
promise.then( result => {
console.log("PRomise Success ...");
}, function(error) {
console.log("Promise Failure...");
});

How to use async and await in gmail read message API

I tried using async/await instead of the callback for reading the Gmail
Here is the code snippet
const {google} = require('googleapis');
async function getRecentMessageBody(auth) {
const gmail = google.gmail({version: 'v1', auth});
try{
const messageId = await gmail.users.messages.list({
userId: 'me',
labelIds: 'INBOX',
maxResults: 1
});
const message = await gmail.users.messages.get({
userId: 'me',
id: messageId.data.messages[0].id,
format : 'full'
});
const value = base64url.decode(message.data.payload.body.data);
console.log(messageId);
//return value ;
}
catch(error) {
console.log('Error occurs while reading mail :'+ error);
throw error;
}
}
But the messageId is undefined
whereas if i use
gmail.users.labels.list({
userId: 'me',
}, (err, res) => {
if (err) return console.log('The API returned an error: ' + err);
const labels = res.data.labels;
if (labels.length) {
console.log('Labels:');
labels.forEach((label) => {
console.log(`- ${label.name}`);
});
} else {
console.log('No labels found.');
}
});
how to fix the issue??
use promisfy to convert callback to promises

DynamoDB.putitem not adding paramaters to DynamoDB table?

My lambda function uses the method
ddb.putItem(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log("SUBMITTED DATA"); // successful response
});
with my params being correctly formatted to my table. No error is shown in my logs, however "SUBMITTED DATA" does not appear in the logs either, and the data is not put into my DynamoDB table. Any idea on what might be causing this problem? Heres my complete function:
const TrackHabitIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'TrackHabitIntent';
},
handle(handlerInput) {
ddb.putItem(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log("SUBMITTED DATA"); // successful response
});
const speechText = "That's awesome! I'll add today to your streak of 4 days";
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Hello World', speechText)
.getResponse();
}};
exports.handler = function (event, context) {
if (!skill) {
skill = Alexa.SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
HelpIntentHandler,
HelpMeIntentHandler,
TrackHabitIntentHandler,
NewHabitIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
)
.addErrorHandlers(ErrorHandler)
.create();
}
return response;
};
Thanks
Please check this code to add data in dynamoDB that can help you.
let putParams = {
TableName: tableName,
Item: {
'Id': {
S: Id
},
'name': {
S: name
}
},
ConditionExpression: 'attribute_exists(Id)'
};
dynamoDb.putItem(putParams, function (err, data) {
if (err) {
console.log('failure:put data from Dynamo error', err);
reject(err);
} else {
console.log('success:put data from Dynamo data');
resolve(data);
}
});

Sails.JS Socket in Overridden Actions of the Controller

I've overridden an action in the controller that was generated from a blueprint API in Sails.JS.
I used the create action. Now I can't get a Sails.JS socket event from that action anymore, however, other actions are working fine.
io.socket.on('posts', function gotHelloMessage(data) {
console.log('Post!', data);
});
io.socket.get('/posts', function gotResponse(body, response) {
console.log('Posts: ', body);
})
What's the way to implement so that the create action also generates the event with my newly implemented actions?
create: function(req, res) {
if (
!_.has(req.body, "title") ||
!_.has(req.body, "body") ||
!_.has(req.body, "category")
) {
return res.serverError("No field should be empty.");
}
var uploadPath = "../../assets/posts";
return req
.file("thumbnail")
.upload({ dirname: uploadPath }, async function(err, uploadedFiles) {
if (err) return res.serverError(err);
let post;
try {
post = await Posts.create({
title: req.body.title,
body: req.body.body,
category: req.body.category,
thumbnail:
uploadedFiles.length === 0
? ""
: uploadedFiles[0].fd.split("/").reverse()[0]
}).fetch();
return res.json({ result: post });
} catch (err) {
return res.json({ error: err });
}
});
}

Resources