How to save a PDF from an REST API call - node.js

I am sending a request to a server via axios. In response I get this code from server. I think it is buffer type thing. Dont't know anything about it.
%PDF-1.3\n' +
'%����\n' +
'1 0 obj\n' +
'<<\n' +
' /CreationDate (D:20201204055104Z)\n' +
' /ModDate (D:20201204055104Z)\n' +
'>>\n' +
'endobj\n' +
'2 0 obj\n' +
I want to save this response in pdf format. I have tried this code but it will only generate blank pdf file.
Here is my code
const url = "https://api-stage-starfleet.delhivery.com/package/DL000246845CN/shipping-label";
// Headers config
const config = {
headers: {
'Accept': 'application/pdf',
'id_token': id_token,
'Authorization': auth_token,
}
}
axios.get(url, config)
.then((response) => {
fs.writeFile("output.pdf", response.data, function (err) {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
})
.catch((err) => {
console.log(err);
})
I have also tried by adding encoding in header object. But it is not working and only generating blank pdf. Can anyone help me on this.

By default, axios will use strings for its response types. In order to tell it to use binary data instead you pass a configuration called responseType:
const config = {
headers: {
'Accept': 'application/pdf',
'id_token': id_token,
'Authorization': auth_token,
},
responseType: 'buffer'; // <-- Here -----
}
Then, your writeFile would work, though note it's far more efficient to just pipe the response from axios to the file:
axios({
method: "get",
headers: {
'Accept': 'application/pdf',
'id_token': id_token,
'Authorization': auth_token,
},
responseType: "stream"
}).then(function (response) {
response.data.pipe(fs.createWriteStream("output.pdf"));
});

Related

react native cannot get appended data in server side

I want to upload image to the database. However, when I use fetch method with 'Content-Type': 'multipart/form-data' but I cannot get the appended data in the server side. It shows that I have no data in the body.
Below is fetching part of the coding
editProfile = () => {
let bodyData = new FormData();
let photo={
uri:this.state.uri,
type:this.state.type,
fileName:this.state.fileName,
}
bodyData.append('transactionCode', 'UPDATEPROFILE');
// bodyData.append('photo', photo);
console.log(bodyData);
fetch(URL, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
},
body: bodyData,
}).then((response) => response.json())
.then((responseJson) => {
alert(responseJson);
})
.catch((error) => {
alert(error);
});
}
This is the example of how i check the data at the server side
const custfunction = function (req, res) {
console.log(req.body);
}
When i console.log(req), it shows body:{} is empty
Alright, I just find out the problem. I need to use Multer to handle multipart/form-data in the backend. Thanks a lot.
https://www.npmjs.com/package/multer

Axios set Content-Length manually, nodeJS

Is there a way to send a post request in nodeJS and specify th content-length.
I tried (using axios):
let data = `Some text data...........`;
let form = await Axios.post(
"url.......",
data,
{
headers: {
Authentication: "token.....",
"Content-Type": "multipart/form-data; boundary=c9236fb18bed42c49590f58f8cc327e3",
//set content-length manually
"Content-Length": "268"
}
}
).catch(e => e);
It doesn't work, the length is set automatically to a value other then the one I pass.
I am using axios but open to using any other way to post from nodeJS.
I can't add a comment because of low reputation, but part of Sandeep Patel's answer regarding Axios is outdated. You can set Content-Length manually. Axios will not override Content-Length if content-length header is present:
// Add Content-Length header if data exists
if (!headerNames['content-length']) {
headers['Content-Length'] = data.length;
}
Source: https://github.com/axios/axios/blob/main/lib/adapters/http.js#L209-L213
So in your case it would be:
let data = `Some text data...`;
let form = await Axios.post(
"url...",
data,
{
headers: {
Authentication: "token....",
"Content-Type": "contentType...",
//set content-length manually
"Content-Length": "268",
"content-length": "268"
}
}
).catch(e => e);
In Axios, If data is present it will set length calculated from data, so even if you pass header content-length, it will be overridden by code:
Check this out for more details:
https://github.com/axios/axios/blob/master/lib/adapters/http.js
Using http or https module you can do:
const https = require('https')
const data = JSON.stringify({
key:values
})
const options = {
hostname: 'example.com',
port: 443,
path: '/testpath',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
}
const req = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', (d) => {
process.stdout.write(d)
})
})
req.on('error', (error) => {
console.error(error)
})
req.write(data)
req.end()

downloading blank pdf when using express to call looker api

When calling render_task_results(render_task_id) looker API from my NodeJS based API using axios I am getting the binary data but when downloading it it is giving me blank PDF.
PFB my code.
const response = await createPdf(TaskID, lookerToken.access_token);
res.set({ 'Content-Type': 'application/pdf', 'Access-Control-Allow-Origin': '*' });
res.status(200).send(response.body);
return res;
export async function createPdf(TaskID, lookerToken): Promise<any> {
return new Promise((resolve) => {
const url = "someurl/api/3.1/render_tasks/" + TaskID + '/results';
const headers = {
'Authorization': 'token ' + lookerToken
};
axios({
headers,
method: 'get',
url: url,
responseType: 'blob'
}).then((response: any) => {
resolve({
body: response.data
//statusCode: response.status,
});
})
});
}

Add track to playlist - post request to spotify API using fetch - not working

I am trying to post a track uri and playlist Id to spotify API in order to add a track to a playlist.
I am using the url params and only one track at a time because spotify say you can do this 'The Spotify URIs of the tracks to add can be passed either in the query string or as a JSON array in the request body.' - spotify
The request hangs, nothing happens. No error, no response. In postman If I use the same bearer auth and url, I get the 'snapshot_id' as response, this is what I am looking for with the code.
I have tried an axios post and a fetch post, both behave the same.
async function updatePlaylist(accessToken, reqParams) {
console.log('PARAMS _', reqParams);
console.log('token _', accessToken);
console.log('trying...');
const url = `https://api.spotify.com/v1/playlists/${reqParams.playlist_id}/tracks?uris=${reqParams.track_uri}`;
return fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + accessToken
},
contentType: 'application/json'
}).then((response) => {
console.log('response promise is ', response.json())
return response;
}).catch(err => {
console.error(err);
throw new Error('Update playlist call failed');
});
}
async function updatePlaylist(accessToken, reqParams) {
console.log('PARAMS _', reqParams);
console.log('token _', accessToken);
console.log('trying...');
const url =
`https://api.spotify.com/v1/playlists/${reqParams.playlist_id}/tracks?uris=${reqParams.track_uri}`;
return axios.post(url, {
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
}
}).then((response) => {
console.log('response promise is ', response)
}).catch(err => {
console.log('errrring ',err)
if (err.response.status === 401) {
return {statusCode: 401};
}
console.error(err);
throw new Error('Get all play lists call failed');
});
}
All my variables are there. I expect the 'snapshot_id' returned back to me confirming the update.
Any help most welcome.
Have you tried setting your content-length to 0 in the headers?
For example in the axios implementation it'd be like this
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json',
'Content-Length': '0'
}
Source

HTTP call to send data to server using Axios/Axios-retry

I have a JSON object that I wish to send to a server using the server's API key. I wish to have a retry count of 3 so that I can retry sending data if previous calls fail.
I am not sure whether to use 'axios-retry' or 'retry-axios'.
How do I configure the Content-Type in the header, and where do I add the API key and the data to be sent. My present code looks like this:
const axiosRetry = require('axios-retry');
axiosRetry(axios, { retries: 3 });
var data = { /*----My JSON Object----*/ };
axios.post('my url', data, {
headers: {
'Authorization': 'API_Key',
'Content-Type': 'application/json'
}
})
.then(function(response){
console.log(response);
})
.catch(function(error){
console.log(error);
});
Use axios instead, it is a Promise based HTTP client for the browser and node.js
var axios = require('axios')
axios.post(url,data, {
headers: {
'authorization': your_token,
'Accept' : 'application/json',
'Content-Type': 'application/json'
}
}).then(response => {
// return response;
}).catch((error) => {
//return error;
});

Resources