Node js to wait till the response comes - node.js

copy_deliverable_script_tomaster(args.Software_name.value,function(state){
res.end("added")
}
)
function copy_deliverable_script_tomaster(software_name,callback){
client.scp('./Temporary_software_files/folder/', {
host: 'ip',
username: 'centos',
privateKey: String(require("fs").readFileSync('./foreman_keypairs/coe-
central.pem')),
path: '/home/centos/Software_with_files/'+software_name
}, function(err,response) {
if(err){
console.log(err)
}
else{
console.log("after copy in master")
return callback(response);
}
})
}
I have used the above code, to copy large files to the remote machine.
Copying file continues in the remote machine, but the response("no content")comes before copy completes.
console.log("after copy in master"), will be printed only after the copy is completed.
Unable to get the response.

Instead of res.end use res.send("added"); or res.write('Added'); res.end();,
Because you have ended response without writing anything.
copy_deliverable_script_tomaster(args.Software_name.value, function (state) {
res.send("added")
})

You are not handling the error case. If you are not doing anything inside callback of client.scp then just pass the callback.
copy_deliverable_script_tomaster(args.Software_name.value, function (err,state) {
if(err) return res.status(400).send(err);
return res.send("some response")
})
function copy_deliverable_script_tomaster(software_name, callback) {
client.scp('./Temporary_software_files/folder/', {
host: 'ip',
username: 'centos',
privateKey: String(require("fs").readFileSync('./foreman_keypairs/coe-central.pem')),
path: '/home/centos/Software_with_files/' + software_name
}, callback)
}

Related

Get file buffer using Google Drive API and async/await

I'm trying to get the buffer of some drive pdf files so I can parse it and use the data.
I've managed to get the file names and id using async/await and a "drive.files.list" wrapped with promise. Now I need to use the file ids to get the buffer and then read it.
The function I need should return a promise that I can wait (using await) to be fulfilled to get a buffer. (My parser works fine when I get pdf buffer from website responses)
function getBuffer(drive, file) {
return new Promise((resolve, reject) => {
/////Google Auth
var jwToken = new google.auth.JWT(
key.client_email,
null,
key.private_key, ["https://www.googleapis.com/auth/drive"],
null
);
jwToken.authorize((authErr) => {
if (authErr) {
return reject([false, "Auth Error: " + authErr]);
}
});
drive.files.get({
auth: jwToken,
fileId: file.id,
alt: 'media',
supportsAllDrives: true
}, function (err, res) {
if (err) {
return reject('The API returned an error: ' + err);
};
console.log(res);
const buffer = res;
resolve(buffer);
});
});
}
And I use it this way:
var buffer = await getBuffer(drive,files[i]);
The output I get in "console.log(res)" is something like this:
...
��M�7�|�ı�[��Ξ�A����EBS]��P��r�����j�3�|�I.��i�+ϢKU���U�:[�═�,^߻t덲�v��=}'*8���ѻ��#ғ�s��No��-��q8E9�/f� �(�`�j'3
"╚�-��� ������[jp&��╚k��M��vy� In�:a�զ�OlN��u����6�n���q�/Y�i4�?&%��q�,��p╚.ZV&n�Ɨ��2G������X����Y
D],�ggb�&�N���G����NS�Lח\U�^R|_f<��f*�|��]�{�3�-P�~�CS��t��>g�Y��#�#7Wjۋ╗=�5�����#ջ���5]>}&v�╝═�wg��eV�^>�#�{��Ѿ��ޤ��>O�� z�?{8Ij�0╗B�.�Cjm�4������║��m�,╗�������O���fS��ӂcE��g�3(�G��}d^O������7����|�
H�N��;
{��x�bȠ�׮�i]=���~��=��ٟ<��C��
wi��'a�-��p═M�6o��ϴ��ve��+��'
...
And when I try to use the parser (pdf2json) I get this error:
"An error occurred while parsing the PDF: stream must have data"
Thanks in advance :D
You want to download a file from Google Drive.
You want to convert the downloaded data to the buffer.
You have already been able to download files from Google Drive using googleapis with Node.js.
If my understanding is correct, how about this modification? In this modification, the file is downloaded as the stream type and the data is converted to the buffer.
Modified script:
From:
drive.files.get({
auth: jwToken,
fileId: file.id,
alt: 'media',
supportsAllDrives: true
}, function (err, res) {
if (err) {
return reject('The API returned an error: ' + err);
};
console.log(res);
const buffer = res;
resolve(buffer);
});
To:
drive.files.get(
{
auth: jwToken,
fileId: file.id,
alt: "media",
supportsAllDrives: true
},
{ responseType: "stream" },
function(err, { data }) {
if (err) {
return reject("The API returned an error: " + err);
}
let buf = [];
data.on("data", function(e) {
buf.push(e);
});
data.on("end", function() {
const buffer = Buffer.concat(buf);
console.log(buffer);
// fs.writeFile("filename", buffer, err => console.log(err)); // For testing
resolve(buffer);
});
}
);
Note:
As a test case, I could confirm that when buffer is saved to a file using fs.writeFile("filename", buffer, err => console.log(err));, the downloaded file can be created.
Reference:
google-api-nodejs-client
If I misunderstood your question and this was not the direction you want, I apologize.

MEAN client-server connection timeout for downloading PDF

I am using MEAN Stack for our project. To generate pdf using pdfmake,
scenario goes like, At first have images from local server so every thing works fine. For scalibility have to move images to AWS and data from other server.
Now processs is like, first download images from aws then make buffer, convert it to base64 and give it to pdfmake. Now issue arises for client-server connection.
client makes http request for pdf, server process it but it takes too much time to download image from aws, so client connection breaks mean while
server processing the request and send response back but no one is there to listen.
/** client **/
function logicTriplogs() {
$rootScope.isLoading = true;
AssignsService.logicTriplogs({
driverId: vm.driver
}, {
_ids: vm.selectedTrips,
scheduleTime: vm.scheduleTime,
companyImage: vm.companyImage
},
function(response) {
console.log(response);
$rootScope.isLoading = false;
var Name = response.pdfName;
var data = response.content;
SaveFile.downloadURI(Name, data);
console.log('PDF Name:', Name);
},
function(err) {
console.log(err);
vm.error = err.data.message;
$rootScope.isLoading = false;
});
}
/** Server **/
getAssignedTripQuery(query, type)
.exec(function(err, assigns) {
if (err) {
console.log('Manifest');
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
}
if (assigns.length) {
logicMan(req.body, user, driver, assigns, function(docDefinition) {
var pdfName = `${moment_tz.tz(startDay, req.user.timeZone).format('MM-DD-YYYY')}.pdf`;
config.pdfBuffer(docDefinition, function(err, pdfDoc) {
console.log('EROROR PDF: ', err);
if (err) {
console.log('pdfmake function call error');
return res.status(400).send({
message: 'Error while generate pdf'
});
}
console.log('PDF Name:', pdfName);
return res.json({
message: 'Generated Susscessfuly',
pdfName: pdfName,
content: pdfDoc
});
});
});
} else {
return res.status(400).send({
message: 'Some thing went wrong. Please try later.'
});
}
});

Meteor : Retrieve value in Meteor.call which calls a server method having promise

I have an internally maintained npm package myNpmPackage which exports a function (for e.g. fnTestMicroSerConn ) as below:
const rp = require('request-promise-native')
exports.fnTestMicroSerConn = function () {
return new Promise(function(resolve, reject) {
var options = {
method: 'GET',
uri : "http://example.net",
resolveWithFullResponse: true,
}
rp(options)
.then(function (response) {
if (response.statusCode !== 200){
console.error("http not 200 but : ",response.statusCode)
resolve(false)
} else {
console.info("connected successfully : "+response.body)
resolve(response)
}
})
.catch(function (err) {
console.error("Error in establishing connectivity : ",err)
resolve(false)
})
})
}
I then need to call the above exported function from a Meteor method like so:
import { Meteor } from 'meteor/meteor';
import myNpmPackage from 'myNpmPackage';
Meteor.methods({
foo: function () {
myNpmPackage.fnTestMicroSerConn().then(function (response){
console.log(" My response: ",response.body);
return(response.body)
})
}
});
console.log(" My response: ",response.body); gets executed successfully and I can see the expected value in the server console log. So till here it's good.
However, now I want to pass the value of response.body to the client side. In short, when I do below on the client :
Meteor.call("foo", function (err, response) {
console.log("calling foo");
if(!err){
console.log("response : ",response);
} else {
console.log("err : ",err);
}
})
Unfortunately, currently I am getting undefined on the client for console.log("response : ",response);
Note: I am using the Meteor Promise package from here
Let me know if any more details are needed or any thing is unclear. I am very new to the Promise style of coding, hence, this can sound as a noob question.
Meteor methods called from clients by Meteor.call run synchronously to prevent clients from pending, even if a callback is supplied.
Your foo method does not wait for that promise inside. It runs past fnTestMicroSerConn() call without hesitation and ends up with no more statement to execute, returning undefined as a result. By the time the promise resolved and logged the expected message on the server console, the method had been exited.
To get resolved/rejected result of that promise, you can return the promise from the method to the caller, and the client would be able to respond to the promise.
Meteor.methods({
foo: function () {
return myNpmPackage.fnTestMicroSerConn();
}
});
Meteor.call("foo")
.then( response => console.log("My response: ", response.body) )
.catch( err => console.log("err : ",err) );
Meteor methods is powerful. The API documentation of methods contains much information and is worth mastery.

how to catch a server response?

There is a client wich is sending requests to my webserver. This Server should answer with data or an specific code, for example 117 (yes this a halo reference :D) Now I need access to the responded data or code. How could I realize this? I found nothing similar here at stackoverflow, may you can help.
Client example:
function sendRequest() {
var options = {
host: 'localhost',
port: 1309,
path: '/examplePath?param='+param,
param: "example"
};
http.get(options, function(resp){
resp.on('data', function(chunk){
console.log("chunk :",chunk);
});
}).on("error", function(err){
console.log("Error: " + err.message);
});
}
Answering Server:
function examplePathFunction(req,res) {
if(condition) {
//TODO Server must answer with data
} else {
//TODO Server must answer with status 117
}
}
Would : res.end(date/code); solve my problem? And how do I catch this response ?
I think you're looking for:
function examplePathFunction(req, res, next) {
if(req.body.data) {
res.status(200).send({ data: req.body.data });
return next();
} else {
res.status(117);
return next();
}
}
Though if you're trying to send data through params, look there rather than the request body.
Read more about the Express API: http://expressjs.com/en/api.html#req

Checking file after creating. FS + timeout?

After ajax request, I send options for Image Magick (child process) and create file.
If I send response to client immediately - I have error - img non exist. My solution, set Timeout and send response (hardcode).
I can set timeout and check file with fs module, but it is right way?
Or may be I can emit new event after file exist, but can you type sample for me?
Or this task have another solution?
fs.stat(currentImage, function(err, background) {
if (background && background.isFile) {
async.series([
function(callback) {
var magickOpts = memOptions;
var im = spawn('convert', magickOpts);
callback(null, 'done');
}
],
function(err, result) {
setTimeout(function() {
res.send({
status: '200',
src: '/images/mems/'+tempName+'.jpg',
tempName: tempName
});
}, 500);
});
} else {
res.send({
status: '404',
text: 'background image not found'
});
}
});
You should wait for the child process to exit (by listening for the close event) before you send the response to the client.
Also, async.series doesn't seem to be really used in this case, so I left it out:
fs.stat(currentImage, function (err, background) {
if (background && background.isFile) {
var magickOpts = memOptions;
var im = spawn('convert', magickOpts);
im.on('close', function() {
res.send({
status: '200',
src: '/images/mems/' + tempName + '.jpg',
tempName: tempName
});
});
} else {
res.send({
status: '404',
text: 'background image not found'
});
}
});
By the way, there's also the im package which wraps ImageMagick for use in Node.

Resources