how to get file content through c# in node js - javascript

I am getting blob of pdf file from other server which is on C# in node server when I am converting it to array buffer it's size is different from C# array buffer size and when I am opening it to browser it gives error "Failed to load PDF document."
This is my server side code
async post(param: any, body: any, endPoint: string, queryParams: string = '')
{
try
{
if(queryParams == '') queryParams = param.destinationSlug + '/' + param.mainBranchId;
const url = splendidAccountsEndPointsEnum.baseUrl + queryParams + endPoint;
const offset = new Date().getTimezoneOffset().toString();
const headerConfig = { headers: { 'X-Api-Key': param.apiKey, 'X-Api-Secret': param.apiSecret, 'X-App-Id': config.get<string>("splendidXAppId"), LocalDateTimeOffset: offset }}
const response = await axios.post(url, body, headerConfig)
.then(function (response: any)
{
return response?.data;
})
.catch(function (error: any)
{
console.log(error);
return error;
});
if (response?.status === 200)
{
console.log('success');
return response?.data;
}
return response;
}
catch (err)
{
console.error(err);
console.log(err);
return err;
}
}
And this is my client side
let response = this.orderService.generateInvoicePrinting(this.selectedRows)
.subscribe((res) => {
var file = new Blob([res], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
saveAs(file, "invoices.pdf");
window.open(fileURL);
this.pdfSrc = fileURL;
this.showPdf = true;
this.showSuccess('Invoices have been generated successfully.');
this.selectedRows = [];
},
error => {
this.showError('Invoices have not been generated successfully.');
});
generateInvoicePrinting(orders: any): Observable<any>
{
const url = `${environment.apiUrl}api/Order/printInvoices/pdf`;
return this.http.post(url, orders, { headers: new HttpHeaders({ 'Content-Type': 'application/json' }), observe: 'response', responseType: 'blob' }).pipe(
map(res => res.body),
);
}

Related

How to save pdf to Cloudant

I want to save the pdf to Cloudant. With the code below, I get an error opening the Attachment in Cloudant. "An error was encountered when processing this file"
I can put fake string data in the "._attachments[name].data" field and it will save.
The Cloudant docs say the data content needs to be in base64 and that is what I am attempting.
Cloudant says "The content must be provided by using BASE64 representation"
function saveFile() {
var doc = {};
var blob = null;
//fileName is from the input field model data
var url = fileName;
fetch(url)
.then((r) => r.blob())
.then((b) => {
blob = b;
return getBase64(blob);
})
.then((blob) => {
console.log(blob);
let name = url._rawValue.name;
doc._id = "testing::" + new Date().getTime();
doc.type = "testing attachment";
doc._attachments = {};
doc._attachments[name] = {};
doc._attachments[name].content_type = "application/pdf";
doc._attachments[name].data = blob.split(",")[1];
console.log("doc: ", doc);
})
.then(() => {
api({
method: "POST",
url: "/webdata",
auth: {
username: process.env.CLOUDANT_USERNAME,
password: process.env.CLOUDANT_PASSWORD,
},
data: doc,
})
.then((response) => {
console.log("result: ", response);
alert("Test has been submitted!");
})
.catch((e) => {
console.log("e: ", e);
alert(e);
});
console.log("finished send test");
});
}
function getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
}
any ideas?
Thanks
CouchDB, and by extension Cloudant, has a means of handling a "multi-part" request where the JSON document and the attachments are sent in the same request. See https://docs.couchdb.org/en/3.2.2/api/document/common.html#put--db-docid
They are modelled in CouchDB's Nano project here: https://www.npmjs.com/package/nano#multipart-functions
const fs = require('fs');
fs.readFile('rabbit.png', (err, data) => {
if (!err) {
await alice.multipart.insert({ foo: 'bar' }, [{name: 'rabbit.png', data: data, content_type: 'image/png'}], 'mydoc')
}
});
Alternatively, you could write the document first and add the attachment in a supplementary request. Using the current Cloudant SDKs:
write document https://cloud.ibm.com/apidocs/cloudant?code=node#putdocument
write attachment https://cloud.ibm.com/apidocs/cloudant?code=node#putattachment
const doc = {
a: 1,
b: 2
}
const res = await service.putDocument({
db: 'events',
docId: 'mydocid',
document: doc
})
const stream = fs.createReadStream('./mypdf.pdf')
await service.putAttachment({
db: 'events',
docId: 'mydocid',
rev: res.result.rev, // we need the _rev of the doc we've just created
attachmentName: 'mypdf',
attachment: stream,
contentType: 'application/pdf'
})
I found out I was doing too much to the PDF file. No need to make to blob then convert to base64.
Only convert to base64.
async function sendFiles() {
try {
const url = fileName;
const doc = {};
doc._attachments = {};
doc._id = "testing::" + new Date().getTime();
doc.type = "testing attachment";
for (let item of url._value) {
const blob2 = await getBase64(item);
let name = item.name;
doc._attachments[name] = {};
doc._attachments[name].content_type = item.type;
doc._attachments[name].data = blob2.split(",")[1];
}
const response = await api({
method: "POST",
url: "/webdata",
data: doc,
});
} catch (e) {
console.log(e);
throw e; // throw error so caller can see the error
}
console.log("finished send test");
fileName.value = null;
}
function getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
}
This works for me.

How to make a resumable upload for attachments through Gmail API in react native?

Please do not share the documentation link, it's not straight forward and also the uploading using RNFS and document-picker is a bit confusing..
Code:
const uploadAttachments = async (data, sessionURI, message, onProgress) => {
const {files} = message;
let length = 0;
const formatedFileData = files.map(item => {
length += item.size;
return {
name: item.filename,
filename: item.filename,
filepath: RNFS.DocumentDirectoryPath + '/' + item.filename,
filetype: item.filetype,
};
});
RNFS.uploadFiles({
toUrl: sessionURI,
files: formatedFileData,
method: 'PUT',
headers: {
Authorization: 'Bearer ' + (await getUserToken()),
'Content-Length': length.toString(),
'Content-Type': 'application/json; charset=UTF-8',
},
fields: data,
progress: onProgress,
})
.promise.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
};
const requestSession = async (data: any, postUrl: string) => {
try {
const result = await axios({
data: data,
headers: {
Authorization: 'Bearer ' + (await getUserToken()),
'Content-Type': 'application/json; charset=UTF-8',
'Content-Length': 0,
'X-Upload-Content-Type': 'message/rfc822',
},
method: 'post',
url: postUrl,
});
return result;
} catch (error) {
throw error;
}
};
export const resumeableUpload = async (message, onProgress) => {
try {
const data = await getMetaData(message);
const response = await requestSession(data, RESUMABLE_URL);
const sessionURI = response.headers.location;
const res = await uploadAttachments(data, sessionURI, message, onProgress);
return res;
} catch (error) {
console.log(error);
}
};
I get the error from RNFS saying the 'Socket is closed'!
May be the way i'm uploading the file itself is wrong or is there any other way to upload files to the session uri?
If I send base64encoded bytes of the file, it raw feild becomes too huge for files over 5MB (25mb files) and the app crashes

Unable to convert file to binary format for sending to wit.ai api using node.js

I am facing an issue in converting Audio file to Binary format. I need to send it to Wit.AI api which is expecting the data in that format. I am using node.js. In my front-end I am recording the user voice using Mic-recorder Module. Any suggestions are welcome.
My front end code:
var recorder;
function startRecording() {
recorder = new MicRecorder({
bitRate: 128
});
recorder.start()
}
function stopRecording() {
recorder.stop().getMp3().then(([buffer, blob]) => {
console.log(buffer, blob);
const file = new File(buffer, 'music.mp3', {
type: blob.type,
lastModified: Date.now()
})
console.log(file)
axios({
method: 'post',
url: `${appUrl}/open_api/voice/send?data=${buffer}`
}).then(function (res) {
console.log(res)
if (res.data.success) {
console.log('done',res)
} else {
console.log(res.data)
}
})
})
};
After recording Successfully, I want to send the file to my api in order to call wit.ai /speech api.
My back end code is:
router.post('/voice/send', //chatbot response api
async (req, res, next) => {
let thread_id = '99-99-99-99'
let audioBinary = req.query.data
console.log(audioBinary)
let appId = "5d07621d6b79be66a73f4005"
let sessionId ="10-10-10-10"
let accessToken = await db.model('ChatBotApp').findOne({
_id: req.query.key
}, {
access_token: 1
}).lean()
var options = {
method: 'POST',
uri: 'https://api.wit.ai/speech?v=20190513',
body : audioBinary,
encoding: null,
headers: {
'Authorization': 'Bearer ' + "HY3ZWSUGPBPD5LWZLRSZ3QJCDC27M6EW",
'Content-Type': 'audio/mpeg',
},
// json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(async function (parsedBody) {
console.log('this called',parsedBody)
return
// let response = await firstEntityValue(parsedBody, appId, message, thread_id)
// events.emit('Chats', appId, thread_id, message, sessionId, response);
return res.apiOk(response)
})
.catch(function (err) {
console.log(err)
return res.apiError('Issue while creating app!', err);
})
}
)
var recorder
function startRecording() {
recorder = new MicRecorder({
bitRate: 128
});
recorder.start()
}
function stopRecording() {
recorder.stop().getMp3().then(([buffer, blob]) => {
console.log(buffer, blob);
const file = new File(buffer, 'music.mp3', {
type: blob.type,
lastModified: Date.now()
})
var bodyFormData = new FormData();
bodyFormData.append('file', file);
console.log(file)
axios({
method: 'post',
url: `${appUrl}/open_api/voice/send`,
headers: {
'Content-Type': 'multipart/form-data'
},
data: bodyFormData
}).then(function (res) {
console.log(res)
if (res.data.success) {
console.log('done', res)
} else {
console.log(res.data)
}
})
})
};
API
router.post('/voice/send',upload.single('file'), //chatbot response api
async (req, res, next) => {
console.log(req.file)
let thread_id = '99-99-99-99'
let audioBinary = req.file.buffer
let appId = "5d07621d6b79be66a73f4005"
let sessionId = "10-10-10-10"
let accessToken = await db.model('ChatBotApp').findOne({
_id: req.query.key
}, {
access_token: 1
}).lean()
var options = {
method: 'POST',
uri: 'https://api.wit.ai/speech?v=20190513',
headers: {
'Authorization': 'Bearer ' + "HY3ZWSUGPBPD5LWZLRSZ3QJCDC27M6EW",
'Content-Type': 'audio/mpeg',
},
body: audioBinary
// json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(async function (parsedBody) {
console.log('this called', parsedBody)
return
// let response = await firstEntityValue(parsedBody, appId, message, thread_id)
// events.emit('Chats', appId, thread_id, message, sessionId, response);
return res.apiOk(response)
})
.catch(function (err) {
console.log(err)
return res.apiError('Issue while creating app!', err);
})
})

Prints out Gibberish PDF file. Angular 6

this is how the binary file looks like.
This is how im subscribing to the method that fetches pdf blob file
public downloadDoc(token: any, docNumber: number) {
this.loading = true;
this._docService.getDocumentStreams(token, docNumber).subscribe(res => {
this.loading = false;
let file = new Blob([res._body], {
type: 'application/pdf'
});
var fileURL = URL.createObjectURL(file);
console.log(res)
window.open(fileURL);
}, (error => {
console.log(`failed to download document: ${error}`);
}))
}
heres the method in service
public getDocumentStreams(token: any, docNumber: number): Observable < any > {
const body = {
'DocNo': docNumber,
'StreamNo': 0
};
const headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('TenantName', 'idl');
headers.append('UseToken', '1');
headers.append('Authorization', 'Basic ' + window.btoa('webapi' + ':' + token));
headers.append('responseType', 'arraybuffer'
as 'json');
return this.http.post(`${this._therefore_apiBase}/GetDocumentStreamRaw`, body, {
headers: headers
}).pipe(
map((response) => {
return response;
}));
}
This prints out a gibberish pdf file what could be the problem

How to send form data in a http post request of angular 2?

I am trying to send form data of the updated user details to the back end which node server in angular 2,However I couldn't send the form data and the server responds with status of 500,In angularjs I have done something like this,
service file
update: {
method: 'POST',
params: {
dest1: 'update'
},
transformRequest: angular.identity,
'headers': {
'Content-Type': undefined
}
}
In controller as
var fd = new FormData();
var user = {
_id: StorageFactory.getUserDetail()._id,
loc: locDetails
};
fd.append('user', angular.toJson(user));
UserService.update(fd).
$promise.then(
function(value) {
console.info(value);
updateUserDetailsInStorage();
},
function(err) {
console.error(err);
}
);
I couldn't to figure how to do this in angular 2 as angular.toJson,angular.identity and transformrequest features are not available in angular 2,
so far I have done the following in angular 2,
let fd = new FormData();
let user = {
_id: this.appManager.getUserDetail()._id,
loc: locDetails
};
fd.append('user', JSON.stringify(user));
this.userService.update(fd).subscribe((value) => {
console.log(value);
this.updateUserDetailsInStorage();
}, (err) => {
console.error(err);
});
http service file
update(body) {
console.log('update', body);
const headers = new Headers({
'Content-Type': undefined
});
const options = new RequestOptions({
headers: headers
});
return this.http.post(`${app.DOMAIN}` + 'user/update', body, options)
.map((res: Response) => {
res.json();
}).do(data => {
console.log('response', data);
})
}
I have read many posts and tried few things but so far it was unsuccessful, could anyone suggest me how to do this?
You can add headers if your server controller requires it else you can simply post it like this
let body = new FormData();
body.append('email', 'emailId');
body.append('password', 'xyz');
this.http.post(url, body);
This is a functional solution for build a POST request in Angular2, you don't need an Authorization header.
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let options = new RequestOptions({ headers: headers });
var body = "firstname=" + user.firstname + "&lastname=" + user.lastname + "&username=" + user.username + "&email=" + user.email + "&password=" + user.password;
return new Promise((resolve) => {
this.http.post("http://XXXXXXXXXXX/users/create", body, options).subscribe((data) => {
if (data.json()) {
resolve(data.json());
} else {
console.log("Error");
}
}
)
});
Here is the method I've used in angular 4 for uploading files....
for Ui
<input type="file"id="file"(change)="handleFileInput($event)">
and .ts file I've added this ....
handleFileInput(event) {
let eventObj: MSInputMethodContext = <MSInputMethodContext> event;
let target: HTMLInputElement = <HTMLInputElement> eventObj.target;
let files: FileList = target.files;
this.fileToUpload = files[0];
console.log(this.fileToUpload);
}
uploadFileToActivity() {
console.log('Uploading file in process...!' + this.fileToUpload );
this.fontService.upload(this.fileToUpload).subscribe(
success => {
console.log(JSON.stringify(this.fileToUpload));
console.log('Uploading file succefully...!');
console.log('Uploading file succefully...!' + JSON.stringify(success));
},
err => console.log(err),
);
}
and In services
upload(fileToUpload: File) {
const headers = new Headers({'enctype': 'multipart/form-data'});
// headers.append('Accept', 'application/json');
const options = new RequestOptions({headers: headers});
const formData: FormData = new FormData();
formData.append('file', fileToUpload, fileToUpload.name);
console.log('before hist the service' + formData);
return this.http
.post(`${this.appSettings.baseUrl}/Containers/avatar/upload/`, formData , options).map(
res => {
const data = res.json();
return data;
}
).catch(this.handleError);
}
This method used for single file uploading to the server directory.
Here is the method from my app which works fine.
updateProfileInformation(user: User) {
this.userSettings.firstName = user.firstName;
this.userSettings.lastName = user.lastName;
this.userSettings.dob = user.dob;
var headers = new Headers();
headers.append('Content-Type', this.constants.jsonContentType);
var s = localStorage.getItem("accessToken");
headers.append("Authorization", "Bearer " + s);
var body = JSON.stringify(this.userSettings);
return this.http.post(this.constants.userUrl + "UpdateUser", body, { headers: headers })
.map((response: Response) => {
var result = response.json();
return result;
})
.catch(this.handleError)
}
FINAL answer
sending like below working fine .
const input = new FormData();
input['payload'] = JSON.stringify(param);
console.log(input);
alert(input);
return this.httpClient.post(this.hostnameService.razor + 'pipelines/' +
workflowId, input).subscribe(value => {
console.log('response for Manual Pipeline ' + value);
return value;
}, err => {
console.log(err);
});

Categories