I'm creating an Electron application and I want to stream an image to a file (so basically download it).
I want to use the native Fetch API because the request module would be a big overhead.
But there is no pipe method on the response, so I can't do something like
fetch('https://imageurl.jpg')
.then(response => response.pipe(fs.createWriteStream('image.jpg')));
So how can I combine fetch
and fs.createWriteStream
?
Writable: streams to which we can write data. For example, fs. createWriteStream() lets us write data to a file using streams. Readable: streams from which data can be read. For example: fs.
The Response interface of the Fetch API represents the response to a request. You can create a new Response object using the Response() constructor, but you are more likely to encounter a Response object being returned as the result of another API operation—for example, a service worker FetchEvent.
Downloading a file using node js can be done using inbuilt packages or with third party libraries. GET method is used on HTTPS to fetch the file which is to be downloaded. createWriteStream() is a method that is used to create a writable stream and receives only one argument, the location where the file is to be saved.
I got it working. I made a function which transforms the response into a readable stream.
const responseToReadable = response => {
const reader = response.body.getReader();
const rs = new Readable();
rs._read = async () => {
const result = await reader.read();
if(!result.done){
rs.push(Buffer.from(result.value));
}else{
rs.push(null);
return;
}
};
return rs;
};
So with it, I can do
fetch('https://imageurl.jpg')
.then(response => responseToReadable(response).pipe(fs.createWriteStream('image.jpg')));
Fetch is not really able to work with nodejs Streams out of the box, because the Stream API in the browser differs from the one nodejs provides, i.e. you can not pipe a browser stream into a nodejs stream or vice versa.
The electron-fetch module seems to solve that for you. Or you can look at this answer: https://stackoverflow.com/a/32545850/2016129 to have a way of downloading files without the need of nodeIntegration.
There is also needle, a smaller alternative to the bulkier request, which of course supports Streams.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With