Request body sometimes null - node.js

The request body sometimes (less than 1% of the time) is null when pulled into lambda. I am processing on the order of 14,000 request bodies one at a time. Any request bodies erring out have to be handled manually. Why is the body randomly coming in null?
Sample code ran from prompt (node index):
const async = require('async');
const _ = require('lodash');
const moment = require('moment');
const Client = require('node-rest-client').Client;
const fs = require('fs');
const input = require('./TestFull.json');
module.exports = () => {
const filename = `./eventfulFails-${new moment().format("YYYY-MM-DD-HHmmss")}.json`;
console.log('Start Time: ', new moment().format("HH:mm:ss"));
let failedObjects = {
events: [],
venues: [],
performers: []
};
async.parallel([
async.apply(processVenues, input.venues, failedObjects),
async.apply(processPerformers, input.performers, failedObjects)
], (lookupErr) => {
if (lookupErr) {
return console.error('Error processing venues and performers.', lookupErr);
}
console.log('Start Events: ', new moment().format("HH:mm:ss"));
async.waterfall([
async.apply(processEvents, input.events, failedObjects)
], (eventErr) => {
if (eventErr) {
console.log('Time of Failure: ', new moment().format("HH:mm:ss"));
return console.error('Error processing events.', eventErr);
}
console.log('End Time: ', new moment().format("HH:mm:ss"));
if (failedObjects.events.length || failedObjects.venues.length || failedObjects.performers.length) {
const stream = fs.createWriteStream(filename);
stream.once('open', function(fd) {
stream.write(JSON.stringify(failedObjects));
stream.end();
});
}
});
});
};
function processVenues(venues, failedObjects, callback) {
const calls = [];
for (let i = 0; i < venues.length; i++) {
const v = venues[i];
calls.push(async.apply((venue, postCallback) => {
const client = new Client();
const args = {
data: venue,
headers: {"Content-Type": "application/json"}
};
client.post('https://hm1br4yo34.execute-api.us-west-2.amazonaws.com/dev/eventful-venue', args, (data, response) => {
if (response.statusCode !== 200 && response.statusCode !== 201) {
failedObjects.venues.push({
venue,
response
});
console.log('venue status code: ', response);
console.log('venue data: ', venue);
}
return postCallback(null);
});
}, v));
}
async.waterfall(calls, callback);
}
function processPerformers(performers, failedObjects, callback) {
const calls = [];
for (let i = 0; i < performers.length; i++) {
const v = performers[i];
calls.push(async.apply((performer, postCallback) => {
const client = new Client();
const args = {
data: performer,
headers: {"Content-Type": "application/json"}
};
client.post('https://hm1br4yo34.execute-api.us-west-2.amazonaws.com/dev/eventful-performer', args, (data, response) => {
if (response.statusCode !== 200 && response.statusCode !== 201) {
failedObjects.performers.push({
performer,
response
});
console.log('performer status code: ', response);
console.log('performer data: ', performer);
}
return postCallback(null);
});
}, v));
}
async.waterfall(calls, callback);
}
function processEvents(events, failedObjects, callback) {
const calls = [];
for (let i = 0; i < events.length; i++) {
const v = events[i];
calls.push(async.apply((event, postCallback) => {
const client = new Client();
const args = {
data: event,
headers: {"Content-Type": "application/json"}
};
client.post('https://hm1br4yo34.execute-api.us-west-2.amazonaws.com/dev/eventful', args, (data, response) => {
if (response.statusCode !== 200 && response.statusCode !== 201) {
failedObjects.events.push({
event,
response
});
console.log('event status code: ', response);
console.log('event data: ', event);
}
return postCallback(null);
});
}, v));
}
async.waterfall(calls, callback);
}
if (!module.parent) {
module.exports();
}
Code of function processVenues (eventful-venue-load) that is called:
const _ = require('lodash');
const AWS = require('aws-sdk');
const async = require('async');
const sdk = require('#consultwithmikellc/withify-sdk');
const host = process.env.aurora_host;
const user = process.env.aurora_user;
const database = process.env.aurora_database;
let decryptedPassword;
const lambda = new AWS.Lambda({
region: 'us-west-2' //your region
});
class WithifyEventCreate extends sdk.Lambda {
constructor(event, context, keysToDecrypt) {
super(event, context, keysToDecrypt);
this.getLocation = this.getLocation.bind(this);
this.insertLocations = this.insertLocations.bind(this);
this.insertLocationImages = this.insertLocationImages.bind(this);
}
decryptedKey(key, value) {
switch (key) {
case 'aurora_password':
decryptedPassword = value;
break;
}
}
initializeComplete() {
this.connect(host, user, decryptedPassword, database, true);
}
connectComplete() {
async.waterfall(
[
this.getLocation,
this.insertLocations,
this.insertLocationImages
]
);
}
getLocation(callback) {
const {id: eventfulLocationID} = this.body;
this.connection.query('SELECT * FROM `Location` WHERE `eventfulLocationID` = ?',
[eventfulLocationID],
(err, results) => {
if (err) {
// error call block
return this.sendResponse(err, this.createResponse(500));
} else if (results.length === 1) {
console.log('Invoking withify-eventful-venue-update...');
lambda.invoke({
FunctionName: 'withify-eventful-venue-update',
Payload: JSON.stringify(this.event)
}, (error, data) => {
return this.sendResponse(null, JSON.parse(data.Payload));
});
} else if (results.length > 1) {
return this.sendResponse(`The location lookup produced multiple results. event:${JSON.stringify(this.body)}`, this.createResponse(500));
} else {
return callback(null);
}
}
);
}
insertLocations(callback) {
const {name: locationName, address: street, city, region_abbr: state, postal_code,
description, id: eventfulLocationID, latitude: lat, longitude: lng, withdrawn: locationWithdrawn} = this.body;
let addresses = street.concat(', ', city, ', ', state, ', ', postal_code);
if (!description.length){
var phones = "";
}else{
var re = /(([\(][0-9]{3}[\)][\s][0-9]{3}[-][0-9]{4})|([0-9]{3}[-][0-9]{3}[-][0-9]{4})|([0-9]{3}[\.][0-9]{3}[\.][0-9]{4}))/i;
this.body.found = description.match(re);
if (!this.body.found){
var phone = "";
}else{
if (!this.body.found.length){
var phone = "";
}else{
var phone = this.body.found[0];
}
}
}
this.connection.query('INSERT IGNORE INTO `Location` (`locationName`, `address`, ' +
'`phone`, `lat`, `lng`, `eventfulLocationID`, `locationWithdrawn`) VALUES (?, ?, ?, ?, ?, ?, ?)',
[locationName, addresses, phone, lat, lng, eventfulLocationID, locationWithdrawn],
(err, results) => {
if (err) {
return this.sendResponse(err, this.createResponse(500));
}
this.body.locationID = results.insertId;
return callback(null);
}
);
}
insertLocationImages(callback) {
var altText = "";
const images = _.flatten(this.body.images.map(im => {
return _.map(im.sizes, (ims, idx) => {
const title = `Image ${idx}`;
return [
this.body.locationID,
this.body.name,
ims.url,
null,
null,
this.body.id,
ims.width,
ims.height
];
});
}));
if(!images[0]){
return this.sendResponse(null, this.createResponse(201, this.body));
}
this.connection.query('INSERT IGNORE INTO `LocationImage` (`locationID`, `imageTitle`, `imageUrl`, ' +
'`imageName`, `altText`, `eventfulLocationID`, `width`, `height`) VALUES ?',
[images],
(err, results) => {
if (err) {
return this.sendResponse(err, this.createResponse(500));
} else if (results.affectedRows !== images.length) {
return this.sendResponse('The image inserts did not affect the right number' +
' of rows.', this.createResponse(500));
}
return this.sendResponse(null, this.createResponse(201, this.body));
}
);
}
}
exports.handler = (event, context) => {
const withifyEventCreate = new WithifyEventCreate(event, context, ['aurora_password']);
withifyEventCreate.initialize([decryptedPassword]);
};

Related

How can I Convert code from Nodejs to Angular including API features [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 days ago.
This post was edited and submitted for review 4 days ago.
Improve this question
I need to convert Nodejs code into Angular. Please suggest me all the steps. I have Nodejs code which is for Get Data using API. That I need to convert into Angular.
I have a task to get Data from Autodesk using their API and Post into MySQL Database (Workbench). This task has already been done in NodeJs. I want to apply same functionality in Angular.
Controller Code : UpdateController.js
const fs = require('fs');
const path = require('path');
const csvtojson = require('csvtojson');
const xlsx = require('xlsx');
const mongoose = require('mongoose');
const openssl = require('openssl-nodejs');
const extract = require('extract-zip');
const SubscriptionsModel = require('../models/subscription');
const PriceListModel = require('../models/pricelist');
const AuthModel = require('../models/auth');
var SubscriptionController = require('../controllers/subscriptioncontroller');
const { sendPasswordNotificationAfterBatch } = require('../models/notification');
var auth = new AuthModel();
class UploadController {
getCSVData(file){
console.log("In getCSVData");
return new Promise((resolve, reject) => {
csvtojson()
.fromFile(file)
.then(csvData => {
//console.log(csvData);
resolve(csvData);
}).catch(err => {
reject(err);
});
});
}
getXLSXData(filename){
console.log("In getXLSData");
return new Promise((resolve, reject) => {
var workbook = xlsx.readFile(filename);
var sheet_list = workbook.SheetNames;
var sheet = workbook.Sheets[sheet_list[0]];
var jsonObjects = xlsx.utils.sheet_to_json(sheet, { range: 7, raw: true, default: null });
var response = [];
response = jsonObjects.filter(item => {
return item.SRP !== undefined && item.SRP !== null && item.DTP !== undefined && item.DTP !== null
});
resolve(response);
}).catch(error => {
throw error;
});
}
updatePricelist(filePath){
return new Promise((resolve, reject) => {
this.getXLSXData(filePath).then(res => {
if(res){
// Delete backup
//PriceListModel.collection.drop();
// Create collection for updated data
PriceListModel.insertMany(res, err => {
if(err){
reject(err);
}
resolve();
})
}
}).catch(error => {
reject(error);
})
});
}
importSubscriptions()
{
console.log("In Import Subscriptions");
var url = `v1/export/subscriptions`;
console.log(`Importing subscription data...`);
return new Promise((resolve,reject) =>{
var body = {
'startDateSince': '2000-01-01'
}
auth.post(url, body).then(function(res)
{
var d = JSON.parse(res);
console.log(d);
resolve(d);
}).catch(err => {
reject(err);
});
});
}
checkImportSubscriptionJobStatus(jobId, count){
var url = `/v1/export/subscriptions/${jobId}`;
console.log(`Checking import subscription job status ${++count}...`);
return new Promise((resolve,reject) =>{
auth.getUsingHttpPlugin(url).then((res) => {
if (res.statusCode == 303) {
console.log("Current status is " + res.statusCode);
resolve(res.headers["location"]);
}
else {
console.log(`Current status is ${res.statusCode}, will retry in 60 seconds again `);
setTimeout(() => {
this.checkImportSubscriptionJobStatus(jobId, count).then(fileUrl => {
resolve(fileUrl);
});
}, '60000');
}
}).catch(function(err){
reject(err);
});
});
}
downloadFile(jobId, fileUrl) {
console.log("Downloading file...");
return new Promise((resolve, reject) => {
var file = fs.createWriteStream(`uploads/subscriptions/${jobId}.csv.zip.enc`);
//console.log(file);
console.log(fileUrl);
auth.getPlainHttp(fileUrl).then(function (response) {
response.pipe(file);
console.log(file.path);
resolve();
}).catch(err => {
console.log("In Catch");
reject(err);
});
});
}
decriptFieUsingOpenSSL(fileName, password) {
console.log("Decrypting file...");
return new Promise((resolve, reject) => {
var encFile = `../uploads/subscriptions/${fileName}.zip.enc`;
var zipFile = `../uploads/subscriptions/${fileName}.zip`;
var openSSLCmd = `enc -aes-256-cbc -md sha512 -d -in ${encFile} -out ${zipFile} -k ${password}`;
console.log('start running openssl command ' + openSSLCmd);
setTimeout(function () {
openssl(openSSLCmd, () => {
resolve();
})
}, 5000);
});
}
updateSubscriptionData(){
return new Promise((resolve, reject) => {
this.importSubscriptions().then(response => {
if(response.error !== undefined){
console.log(`Error Code: ${response.error.code}`);
console.log(`Message: ${response.error.message}`);
reject();
}else{
var id = response.id;
var password = response.password;
this.checkImportSubscriptionJobStatus(id, 0).then(fileUrl => {
this.downloadFile(id, fileUrl).then(() => {
var fileName = `${id}.csv`;
this.decriptFieUsingOpenSSL(fileName, password).then(() => {
console.log("File decrypted successfully...");
var targetFolder = path.join(__dirname, '..', 'uploads', 'subscriptions');
var zipFile = path.join(targetFolder, `${fileName}.zip`);
extract(zipFile, { dir : targetFolder }).then(() => {
console.log("Extracted file successfully");
var fullFileName = path.join(targetFolder, fileName);
this.getCSVData(fullFileName).then(res => {
if(res){
SubscriptionController.updateSubscriptions(res).then(data => {
resolve('Subscriptions data replicated successfully!!!');
console.log("CHECK NOTIFICATION");
sendPasswordNotificationAfterBatch();
}).catch(err => {
throw err;
});
}
}).catch(error => {
reject(error);
})
})
});
});
});
}
}).catch(err => {
reject(err);
})
});
}
}
module.exports = new UploadController();
Model Code : auth.js
var CryptoJS = require("crypto-js");
var request = require("request");
var httpRequest = require("http");
var httpsRequest = require("https");
var config = require('../config.json');
class AuthModel {
constructor() {
this.timestamp = Math.floor((new Date()).getTime() / 1000);
this.consumer_key = config.app.consmer_key;
this.consumer_secret = config.app.consumer_secret;
this.callback_url = config.app.callback_url;
this.partner_csn = config.app.partner_csn;
this.environment_url_stg = "enterprise-api-stg.autodesk.com"; //STG Environment
this.environment_url_prd = "enterprise-api.autodesk.com"; //prd Environment
this.access_token = '';
this.api_timestamp = '';
}
getbaseUrl()
{
var env = config && config.app.env;
console.log("ENVIRONMENT");
console.log(env);
if(env == 'prd')
{
return this.environment_url_prd;
console.log("ENVIRONMENT URL PID");
console.log(this.environment_url_prd);
}
else{
return this.environment_url_stg;
console.log("ENVRIONMENT URL STG");
console.log(this.environment_url_stg);
}
}
get(url, headerData){
var self = this;
return new Promise((resolve, reject) =>{
self.getAccessToken().then(function(token){
var time = Math.floor(Date.now() / 1000);
var header = {
'CSN': self.partner_csn,
'signature': self.getAPISignature(token),
'timestamp': self.api_timestamp,
'Authorization': "Bearer " + token
};
var options = {
method: 'GET',
url: `https://${ self.getbaseUrl() }/${url}`,
headers:header
};
request(options, function (error, response, body) {
if (error) {
reject(error);
}
resolve(body);
});
}).catch(function(err){
reject(err);
});
});
}
post(url, body){
console.log(url);
var self = this;
return new Promise((resolve, reject) =>{
self.getAccessToken().then(function(token){
var time = Math.floor(Date.now() / 1000);
var headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${token}`,
'signature': self.getAPISignature(token),
'timestamp': self.api_timestamp,
'CSN': self.partner_csn
};
var options = {
method: 'POST',
url: `https://${ self.getbaseUrl() }/${url}`,
headers,
form: body
};
request(options, function (error, response) {
if (error){
reject(error);
}
resolve(response.body);
});
}).catch(function(err){
reject(err);
});
});
}
getAPISignature(token)
{
this.api_timestamp = Math.floor(Date.now() / 1000);
var message = this.callback_url + token + this.api_timestamp;
var hash = CryptoJS.HmacSHA256(message, this.consumer_secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
return hashInBase64;
}
createSignature(time)
{
var message = this.callback_url + this.consumer_key + time;
console.log(message);
var hash = CryptoJS.HmacSHA256(message, this.consumer_secret);
console.log(this.consumer_key);
console.log(this.consumer_secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
return hashInBase64;
}
createAuthorization(){
var passwordSignature = this.consumer_key + ":" + this.consumer_secret;
console.log(passwordSignature);
var authorization = Buffer.from(passwordSignature).toString('base64')
console.log("Authorization");
console.log(authorization);
return "Basic " + authorization;
}
getAccessToken(){
console.log("IN GetAccessToken");
var self = this;
var time = Math.floor((new Date()).getTime() / 1000);
return new Promise((resolve, reject) =>{
var options = {
method: 'POST',
url:`https://${self.getbaseUrl()}/v2/oauth/generateaccesstoken?grant_type=client_credentials`,
headers: {
timestamp: time,
signature: self.createSignature(time),
Authorization : self.createAuthorization()
}
};
request(options, function (error, response, body) {
if (error) {
reject(error);
}
resolve(JSON.parse(body).access_token);
console.log(JSON.parse(body).access_token);
});
});
}
getUsingHttpPlugin(url, headerData) {
var self = this;
return new Promise((resolve, reject) => {
self.getAccessToken().then(function (token) {
console.log("Get Access Token");
console.log(token);
var time = Math.floor(Date.now() / 1000);
var header = {
'CSN': self.partner_csn,
'signature': self.getAPISignature(token),
'timestamp': self.api_timestamp,
'Authorization': "Bearer " + token
};
var options = {
method: 'GET',
host: `${self.getbaseUrl()}`,
path: `${url}`,
headers: header
};
var s = httpRequest.request(options, (res) => {
resolve(res);
});
s.end();
}).catch(function (err) {
reject(err);
});
});
}
getPlainHttp(url) {
console.log("URL");
console.log(url);
return new Promise((resolve, reject) => {
console.log("In 1");
var s = httpsRequest.get(url, (res) => {
console.log("RESPONSE STATUS CODE");
console.log(res.statusCode);
if (res.statusCode > 200) {
reject(res);
}
resolve(res);
})
s.end();
});
}
}
module.exports = AuthModel;
If any other Node code needed from my side, I am happy to share.

How to consume a RESTful API in Node.js

I'm new to Node.js and I'm creating a simple pagination page. The REST API works fine, but consuming it has left me in limbo.
Here is the REST API (other parts have been taken out for brevity)
const data = req.query.pageNo;
const pageNo =
(typeof data === 'undefined' || data < 1) ? 1 : parseInt(req.query.pageNo);
let query = {};
const total = 10;
query.skip = (total * pageNo) - total;
query.limit = total;
try {
const totalCount = await Users.countDocuments();
const pageTotal = Math.ceil(totalCount / total);
const users = await Users.find({}, {}, query);
return res.status(200).json(users);
} catch (error) {
console.log('Error ', error);
return res.status(400).send(error)
};
};
When I return the json with just the 'users' object, like so return res.status(200).json(users); the page renders correctly, but when I pass in other objects like what I have in the code, it fails. This is how I'm consuming the API:
const renderHomepage = (req, res, responseBody) => {
let message = null;
if (!(responseBody instanceof Array)) {
message = 'API lookup error';
responseBody = [];
} else {
if (!responseBody.length) {
message = 'No users found nearby';
}
}
res.render('users-list', {
title: 'Home Page',
users: responseBody,
message: message
});
}
const homelist = (req, res) => {
const path = '/api/users';
const requestOptions = {
url: `${apiOptions.server}${path}`,
method: 'GET',
json: true,
};
request(
requestOptions,
(err, {statusCode}, body) => {
if (err) {
console.log('Ther was an error ', err);
} else if (statusCode === 200 && body.length) {
renderHomepage(req, res, body);
} else if (statusCode !== 200 && !body.length) {
console.log('error ',statusCode);
}
}
);
}
I've searched extensively on both here and other resources but none of the solutions quite answers my question. I hope someone could be of help

How can write a column in tsv file using node js?

I have to write a json response in a column of tsv file how can I do that?
I am using the following code. Please find me a solution? I have to check it but its not working.
//npm init -y gen package.json file
var unProcessedItems = [];
var data = loadData('./Alabama_Pre_Final.tsv');
async function X(i) {
if (data[i] && data[i][7]) {
console.log(data[i][7]);
function address(address_details) {
request({
url: 'https://us-extract.api.smartystreets.com/?auth-id=xxx&auth-token=xxx',
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: address_details,
},
(error, response, body) => {
if (!error && response.statusCode == 200) {
var res = JSON.parse(body);
let objectArray = [];
if (res.addresses[0].verified) {
objectArray.push(res.addresses[0].api_output[0].delivery_line_1, res.addresses[0].api_output[0].last_line, res.addresses[0].api_output[0].delivery_point_barcode)
}
var address_data = objectArray.join([separator = ','])
console.log(address_data)
}
});
}
address("1000 Greenhill Blvd NW, Fort Payne, 35967, AL, USA");
const data = 'Column 19\n1\t2\t3\n4\t5\t6';
require('fs').writeFileSync('./Alabama_Pre_Final.tsv', data);
// i++;
// X(i);
}
}
}
I've looked at your answer above I think it should be easy enough to modify so that it works as you expect, I've done this below. The other functions should be left unchanged. So the function X processes each row then returns a record variable which we append to the records array. After processing is complete we write the records array to the csv file.
async function loadData(filePath) {
if (fs.existsSync(filePath)) {
var tsvData = fs.readFileSync(filePath, 'utf-8');
var rowCount = 0;
var scenarios = [];
parse_tsv(tsvData, (row) => {
rowCount++;
if (rowCount > 1) {
scenarios.push(row);
}
});
return scenarios;
} else {
console.log("loadData: Returning empty..")
return [];
}
}
// Process a row of TSV data
function X(row) {
return new Promise((resolve, reject) => {
if (row && row[7]) {
console.log(row[7]);
request({
url: 'https://us-extract.api.smartystreets.com/?auth-id=e62698e8-c3fc-b929-0f5b-d3b54d0bcd0c&auth-token=cibfMexBdl3HrmwbWY6p',
method: 'POST',
headers: { 'content-type': 'application/json' },
body: row[7],
},
(error, response, body) => {
if (!error && response.statusCode == 200) {
var res = JSON.parse(body);
let objectArray = [];
if (res.addresses[0].verified) {
objectArray.push(res.addresses[0].api_output[0].delivery_line_1, res.addresses[0].api_output[0].components.city_name,
res.addresses[0].api_output[0].components.zipcode, res.addresses[0].api_output[0].components.state_abbreviation)
}
var address_data = objectArray.join([separator = ','])
resolve({ name: address_data.replace(/['"]+/g, '') });
} else if (error) {
reject(error);
} else {
reject( { statusCode: response.statusCode });
}
});
}
});
}
async function processData() {
let MAX_RECORDS = 5; // Change as appropriate
var data = await loadData('./Alabama_Pre_Final.tsv');
if (data.length > 0) {
unProcessedItems = [];
let records = [];
for(let row of data) {
// Process a row of data.
let record = await X(row);
records.push(record);
if (records.length === MAX_RECORDS) break;
}
console.log(records);
csvWriter.writeRecords(records)
.then(() => console.log('The CSV file was written successfully'));
} else {
console.log("No Data");
}
}
processData();
const fs = require('fs');
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
var rp = require('request-promise');
var dataToWrite;
var http = require("http");
var request = require('request');
function loadData(filePath) {
if (fs.existsSync(filePath)) {
var tsvData = fs.readFileSync(filePath, 'utf-8');
var rowCount = 0;
var scenarios = [];
parse_tsv(tsvData, (row) => {
rowCount++;
if (rowCount > 1) {
scenarios.push(row);
}
});
return scenarios;
} else {
return [];
}
}
function parse_tsv(s, f) {
var ix_end = 0;
for (var ix = 0; ix < s.length; ix = ix_end + 1) {
ix_end = s.indexOf('\n', ix);
if (ix_end == -1) {
ix_end = s.length;
}
//var row = s.substring(ix, ix_end - 1).split('\t');
var row = s.substring(ix, ix_end).split('\t');
f(row);
}
}
var unProcessedItems = [];
var data = loadData('./Alabama_Pre_Final.tsv');
var records = [];
async function X(i) {
if (data[i] && data[i][7]) {
console.log(data[i][7]);
var options = {
method: 'POST',
url: 'https://us-extract.api.smartystreets.com/?auth-id=c64de073-9531-9444-35e6-7204d9d62c36&auth-token=e5FxYc1niUD7Cp0peixd',
headers: {
'content-type': 'application/json'
},
body: data[i][7],
json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(function (parsedBody) {
// POST succeeded...
var res = parsedBody;
let objectArray = [];
if (res.addresses.length) {
if (res.addresses[0].verified) {
objectArray.push(res.addresses[0].api_output[0].delivery_line_1, res.addresses[0].api_output[0].components.city_name,
res.addresses[0].api_output[0].components.zipcode, res.addresses[0].api_output[0].components.state_abbreviation)
}
var address_data = objectArray.join([separator = ','])
console.log(address_data)
// records.push({ name: address_data.replace(/['"]+/g, '') });
const ADDRESS_COLUMN_INDEX = 7;
for(let row of address_data) {
row[ADDRESS_COLUMN_INDEX] = await X(row[ADDRESS_COLUMN_INDEX]);
}
records.push(address_data.replace(/['"]+/g, ''));
let output = records.map(row => row.join("\t")).join("\n");
i++;
if (i <= 7) {
X(i);
}
else {
fs.writeFileSync('out.tsv', output);
console.log('The TSV file was written successfully');
// return callback(records);
}
}
});
}
// console.log(records);
}
if (data.length > 0) {
unProcessedItems = [];
X(0);
} else {
console.log("No Data");
}
I've updated this answer based on your last revisions, I hope this helps you:
function loadData(filePath) {
if (fs.existsSync(filePath)) {
var tsvData = fs.readFileSync(filePath, 'utf-8');
var rowCount = 0;
var scenarios = [];
parse_tsv(tsvData, (row) => {
rowCount++;
if (rowCount > 1) {
scenarios.push(row);
}
});
return scenarios;
} else {
return [];
}
}
function parse_tsv(s, f) {
var ix_end = 0;
for (var ix = 0; ix < s.length; ix = ix_end + 1) {
ix_end = s.indexOf('\n', ix);
if (ix_end == -1) {
ix_end = s.length;
}
var row = s.substring(ix, ix_end).split('\t');
f(row);
}
}
var unProcessedItems = [];
var data = loadData('./Alabama_Pre_Final.tsv');
var records = [];
async function X(i) {
if (data[i] && data[i][7]) {
console.log(data[i][7]);
var options = {
method: 'POST',
url: 'https://us-extract.api.smartystreets.com/?auth-id=c64de073-9531-9444-35e6-7204d9d62c36&auth-token=e5FxYc1niUD7Cp0peixd',
headers: {
'content-type': 'application/json'
},
body: data[i][7],
json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(async function (parsedBody) {
// POST succeeded...
var res = parsedBody;
let objectArray = [];
if (res.addresses.length) {
if (res.addresses[0].verified) {
objectArray.push(res.addresses[0].api_output[0].delivery_line_1, res.addresses[0].api_output[0].components.city_name,
res.addresses[0].api_output[0].components.zipcode, res.addresses[0].api_output[0].components.state_abbreviation)
}
var address_data = objectArray.join([separator = ','])
console.log("rp.then -> address_data:",address_data);
data[i][7] = address_data.replace(/['"]+/g, '');
records.push(data[i].join("\t"));
i++;
if (i <= 7) {
console.log("Looking up address #" + i);
X(i);
} else {
const output = records.join("\n");
// Remove the _test when you are happy with the result.
fs.writeFileSync('./Alabama_Pre_Final_test.tsv', output);
console.log('The TSV file was written successfully');
}
}
});
}
}
if (data.length > 0) {
unProcessedItems = [];
X(0);
} else {
console.log("No Data");
}

Waiting for one callback to be done (to get data) before the other

I am trying to get MedGuideURL to be used in the 2nd callback but it's value is empty.It seems the second callback is always happening before the first one is done. I am thinking of using Promise/Observable but is there an easier way?
var qrImage = require('qr-image');
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region:'us-west-2'});
exports.handler = function(event, context, callback){
var path = event.path;
var drugId = path.replace(/\//g, '');
var MedGuideURL = "";
var params = {
TableName: 'QRCodeInfo',
Key: {
"DrugId" : drugId
}
};
docClient.get(params, function(err,data) {
if (err) {
callback(err,null);
} else {
console.log("The data is: "+ data.Item.MedGuideURL); //correct value
callback(null,data);
MedGuideURL = data.Item.MedGuideURL;
}
});
callback(null, sendRes(200, MedGuideURL)); //MedGuideURL is empty!
};
const sendRes = (status, body) => {
//console.log(body);
const svg_string = qrImage.imageSync(body, { type: 'svg', size: 10 });
var response = {
statusCode: status,
headers: {
"Content-Type": "image/svg+xml"
},
body: svg_string
};
return response;
};
You need to first understand async behavior.
You have doing callback before method get complete
You can change get with promise
Example
if sendResis promise method
exports.handler = function (event, context, callback) {
var path = event.path;
var drugId = path.replace(/\//g, '');
var MedGuideURL = "";
var params = {
TableName: 'QRCodeInfo',
Key: {
"DrugId": drugId
}
};
docClient.get(params).promise().then((data) => {
console.log('success' + x);
console.log("The data is: " + data.Item.MedGuideURL);
MedGuideURL = data.Item.MedGuideURL;
return sendRes(200, MedGuideURL); //if sendResis promise method
}).then((finalResponse) => {
callback(null, finalResponse);
})
.catch((err) => {
callback(err, null);
})
};
IF sendResis is not promise :
exports.handler = function (event, context, callback) {
var path = event.path;
var drugId = path.replace(/\//g, '');
var MedGuideURL = "";
var params = {
TableName: 'QRCodeInfo',
Key: {
"DrugId": drugId
}
};
docClient.get(params).promise().then((data) => {
console.log('success' + x);
console.log("The data is: " + data.Item.MedGuideURL);
MedGuideURL = data.Item.MedGuideURL;
let finalResponse = sendRes(200, MedGuideURL); //if sendResis not promise method
return callback(null, finalResponse);
})
.catch((err) => {
callback(err, null);
})
};

Is not a function error with module.exports

when i try to callSendAPI in waether.js it shows error not callSendAPI is not a function
weather.js
const request = require('request');
const config = require('./config');
const messages = require('./messages');
weatherAsQuickReply = (messageData) => {
let replies = [{
"content_type": "location"
}];
let sendQuickReply = {
recipient: {
id: messageData.recipient.id
},
message: {
text: messageData.message.text,
quick_replies: replies
}
};
messages.callSendAPI(sendQuickReply);
}
getWeather = (result, messageData) => {
let city = result.parameters["geo-city"];
if (city != '') {
request({
url: 'https://api.apixu.com/v1/current.json',
qs: {
q: city,
key: config.WEATHER_APP_ID,
},
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
let weather = JSON.parse(body);
if (weather.hasOwnProperty("current")) {
let reply = `Location: ${weather.location.region}
Temperature: ${weather.current.temp_c},
${weather.current.condition.text}`;
messageData.message.text = reply;
messages.callSendAPI(messageData);
};
} else {
return res.status(400).json({
status: {
code: 400,
errorType: 'I failed to look up the city name.'
}
});
}
});
} else {
weatherAsQuickReply(messageData);
}
}
module.exports = {
weatherAsQuickReply: weatherAsQuickReply,
getWeather: getWeather
}
message.js
const request = require('request');
const config = require('./config');
const weather = require('./weather');
const apiaiApp = require('apiai')(config.API_AI_CLIENT_ACCESS_TOKEN);
callSendAPI = (messageData) => {
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: {
access_token: config.FB_PAGE_TOKEN
},
method: 'POST',
json: messageData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
}
sendMessage = (event) => {
let sender = event.sender.id;
let text = event.message.text;
let apiai = apiaiApp.textRequest(text, {
sessionId: 'minaaaaa213'
});
apiai.on('response', (response) => {
console.log(response);
let aiText = response.result.fulfillment.speech;
let result = response.result;
let messageData = {
recipient: {id: sender},
message: {text: aiText}
};
if (response.result.action === 'weather') {
console.log('weather');
weather.getWeather(result, messageData);
} else {
callSendAPI(messageData);
}
});
apiai.on('error', (error) => {
console.log('err: ' + error);
});
apiai.end();
}
module.exports = {
callSendAPI: callSendAPI,
sendMessage: sendMessage
}
Try with this,
you are tring to do something inrelevent that is not supported.
const request = require('request');
const config = require('./config');
const {weatherAsQuickReply,getWeather} = require('./temp2');
const callSendAPI = (messageData) => {
......
}
const sendMessage = (event) => {
let sender = event.sender.id;
let text = event.message.text;
let apiai = apiaiApp.textRequest(text, {
sessionId: 'minaaaaa213'
});
apiai.on('response', (response) => {
...
});
}
module.exports = {
callSendAPI,
sendMessage
}
Second File
const request = require('request');
const config = require('./config');
const {callSendAPI,sendMessage} = require('./temp');
const weatherAsQuickReply = (messageData) => {
...
callSendAPI(sendQuickReply);
}
const getWeather = (result, messageData) => {
// Direct call Function like this
weatherAsQuickReply(messageData);
}
module.exports = {
weatherAsQuickReply,
getWeather
}

Resources