Express.js - hit url to download file from api - javascript

I am working with shopify admin api. I create a bulk operation and in return it gives me a url. When you hit this url it automatically downloads the file. This file as information that my server needs.
So where I am at - I send the request for bulk operation, then I hit the url to download file and file gets downloaded by my browser.
What I need is to hit the url, and then download and save the file into a folder on my server where I can then start working with it. And I dont know how to do this, I tried, I looked around. Any help would be awesome. Thanks.
My code:
app.get("/postBulkProds", async (req,res) => {
let url = GRAPHQL_CUSTOM_URL;
await fetch(url, postBulkProducts())
.then(res=> res.json())
.then(bulk => res.send(bulk))
.catch(error => res.send(error));
});
app.get("/getBulkProds", async(req,res, next) => {
let data;
let url = GRAPHQL_CUSTOM_URL;
await fetch(url, getBulkProducts())
.then(products=> (products.json(products)))
.then(products => (data = products))
.catch(error => res.send(error));
console.log(data.data.currentBulkOperation.url);
res.locals.bulk = data;
let url2 = data.data.currentBulkOperation.url;
res.redirect(url2);
});
EDIT-SOLVED
fetch(url2)
.then(r => r.text())
//.then( t=> console.log(t))
.then(t => {let json=JSON.stringify(t);
//console.log(json);
fs.writeFile('./myfile.jsonl', json, err => {
if(err){
console.log("error writing", err);
} else {
console.log("success");
}
})
})
.catch(error => console.log(error));

Related

Why Axios response doesn't console log result?

I'm working on an backend API but at some point I need to get user data from another API. I am trying to use Axios to make http request in order to do that. The request return the result in the browser as expected but the problem is that I can't display console log in the terminal. It doesn't show anything even though I asked the program to do so. Is there a problem probably with my code?
Here is my code :
const axios = require('axios');
const AxiosLogger = require('axios-logger');
const instance = axios.create();
module.exports = (router) => {
router.get('/profile', function(req, res) {
//random fake profile info
axios.get('https://randomuser.me/api/')
.then(response => {
console.log(response.data);
console.log(response.data);
return response.data
})
.catch(error => {
console.log(error);
});
});
};
I would suggest trying response.send to forward the axios response to your client like so:
module.exports = (router) => {
router.get('/profile', function(req, res) {
//random fake profile info
axios.get('https://randomuser.me/api/')
.then(response => {
console.log(response.data);
// Send the axios response to the client...
res.send(response.data)
})
.catch(error => {
console.log(error);
});
});
};

How to convert BLOB into PDF file in the Node environment?

I have a Node Js server, in it, I am fetching a blob data from another web service (which is for a PDF file), now after receiving blob, I want to convert it again into PDF file.
Anyone, who knows how to achieve this please help.
Here is my code block I have tried so far:
const fetch = require('node-fetch');
const Blob = require('fetch-blob');
const fs = require('fs');
fetch(url, options)
.then(res => {
console.log(res);
res.blob().then(async (data) => {
const result = data.stream();
// below line of code saves a blank pdf file
fs.createWriteStream(objectId + '.pdf').write(result);
})
})
.catch(e => {
console.log(e);
});
Modification points:
For fs.createWriteStream(objectId + '.pdf').write(data), please modify res.blob() to res.buffer().
Please modify .then(res => {res.blob().then() to .then(res => res.buffer()).then(.
Modified script:
fetch(url, options)
.then(res => res.buffer())
.then(data => {
fs.createWriteStream(objectId + '.pdf').write(data);
})
.catch(e => {
console.log(e);
});
Note:
In this modification, it supposes that the fetch process using url and options works fine.
References:
node-fetch
write()

Getting empty array from get

When i'm going to localhost:3000/api/categories i'm getting an empty array, but when i log my products there is alot of data inside the object. Anyone knows what i'm doing wrong? Thanks!
let products = getData()
function getData() {
return fetch('some url',
{
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}
).then(res => res.json())
};
app.get(('/api/categories'), (req, res) => {
products.then(console.log);
res.send(products);
products.then(console.log);
});
products is a promise. You can't send it to the client via res.send.
Instead, do what you're doing when you log it: use then:
app.get(('/api/categories'), (req, res) => {
products
.then(data => res.send(data))
.catch(error => {
// Send an error
});
});
Note that your code gets the products once, at startup, and then responds to the request with that static set of products.
If you want to get the products in response to the request from the client, remove the
let products = getData();
and put it in the get handler:
app.get(('/api/categories'), (req, res) => {
this.getData()
.then(data => res.send(data))
.catch(error => {
// Send an error
});
});
That repeats the request each time the client calls your server.
Of course, you might consider a middle ground, keeping and reusing the data for X seconds...

fetch JSON works in node but fails in broser (JSON.parse unexpected end of data at line 1 column 1)

I'm trying to get a json file from an api, when using this code on node.js it works perfectly fine and I can see the results I'm looking for, but when I try to use it from the browser it fails and returns with the error message on the title.
async function searchVolumes(volume, url, apiKey) {
let result = await fetch(url, {mode: 'no-cors'})
.then(res => res.json())
.then(json => json.results)
.catch(error => console.log('Error reading data ' + error))
return result
}
I've tried it in Firefox and Edge and have the same problem in both of them, but checking the network tab I can see the result and the json is fine with no errors, and as I say at the beginning it works on node too.
I modified it according to sideshowbarker links and removed the no-cors mode and added a proxy cors anywhere server and it's working now:
const proxy = 'https://cors-anywhere.herokuapp.com/'
url += proxy
async function searchVolumes(volume, url, apiKey) {
let result = await fetch(url)
.then(res => res.json())
.then(json => json.results)
.catch(error => console.log('Error reading data ' + error))
return result
}

React + Node/Express | Rendering a PDF binary stream blob in React

In React I have hyperlinks which initiate a fetch for PDF files from a backend Node server with Express. The issue is that the stream opens a new window of binary text instead of a PDF file.
React frontend:
//Link
<a href={'#'} onClick={() => this.renderPDF(row.row.pdfid)}> {row.row.commonName}.pdf</a>
//Fetch call
renderPDF = (pdfLink) => {
fetch('http://localhost:8000/pdf' + '?q=' + pdfLink, {
method: 'GET'
//credentials: 'include'
})
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob))
.then(url => window.open(url))
.catch(error => this.setState({
error,
isLoading: false
}));
}
Node backend:
app.get('/pdf', (req, res) => {
let readStream = fs.createReadStream(req.query["q"]);
let chunks = [];
// When the stream is done being read, end the response
readStream.on('close', () => {
res.end()
})
// Stream chunks to response
readStream.pipe(res)
});
Any input would be much appreciated.
Updating your code,
app.get('/pdf', (req, res) => {
let readStream = fs.createReadStream(req.query["q"]);
let stat = fs.statSync(req.query["q"]);
// When the stream is done being read, end the response
readStream.on('close', () => {
res.end()
})
// Stream chunks to response
res.setHeader('Content-Length', stat.size);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'inline; filename=test.pdf');
readStream.pipe(res);
});
Try with this now. Also, check if you get the query['q'] and is not undefined or empty just to validate on error side.

Categories

Resources