'Axios error: ... .data.pipe is not a function
So I am basically trying to use axios to download a image from a url, but I get this error:
TypeError: streamResponse.data.pipe is not a function
My function for doing this image download is below (note that this is inside a class):
/**
* Download poster
*/
async downloadPoster() {
// Writer stream where we want to download the poster image
const writer = fs.createWriteStream(this.poster.file);
// This grabs the second part of the image url that we want
const resultsResponse = await axios({
url: this.poster.url,
method: 'GET',
responseType: 'json',
adapter: httpAdapter
});
// Zero results
if (resultsResponse.data.total_results <= 0) {
logger.log(language[Config.language].posterNotFound + this.movie.title, 'error');
return false;
}
// Create the poster download URL
var posterDownloadUrl = new URL(Config.api.posterUrl + resultsResponse.data.results[0].poster_path);
const streamResponse = await axios({
url: posterDownloadUrl,
method: 'GET',
responseType: 'stream',
adapter: xhrAdapter
});
// Write data
streamResponse.data.pipe(writer);
return new Promise((resolve, reject) => {
writer.on('finish', resolve);
writer.on('error', reject);
});
}
I assume that the adapter for a stream response is the xhr one. Anyways, I have tried both adapters and both gives the exact same error. Both requests does happen though (I can see them in the devtools).
And so there's no confusion, I have the adapters imported at the top of the file:
const httpAdapter = require('axios/lib/adapters/http');
const xhrAdapter = require('axios/lib/adapters/xhr');
What could I be doing wrong here?
Solution 1:[1]
Got it working by sending the download request over to the main thread. Don't know why, but seems you can't access the axios data from a stream in the renderer.js
file. Got it working now though after having a look here:
Solution 2:[2]
here is a simpler version of your code.
Code:
const downloadImage = async (url) => {
// Writer stream where we want to download the image
const writer = fs.createWriteStream("./image.png");
const streamResponse = await axios({
url,
method: 'GET',
// that the point!!!
// change responseType to stream
// pipe only work with 'stream'
responseType: 'stream'
});
// Write data
streamResponse.data.pipe(writer);
writer.on('finish', () => console.log("Finished"));
writer.on('error', () => console.error("Error while dowloading image"));
}
const imageLink = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/1200px-Image_created_with_a_mobile_phone.png";
downloadImage(imageLink);
Solution 3:[3]
if you use electron this is an alternative. in quasar it works perfectly. Remember to put in the main.js
of electron nodeIntegration = true
const fs = require('fs-extra');
import path from 'path';
let url = 'yourl.com';
axios({
url,
method: 'GET',
responseType: 'blob'
}).then((res) => {
let fileName='myfile.zip'
const dir = path.dirname(__dirname);
const Path = path.resolve(`${dir}/dir`, 'subdir', fileName);
const output = fs.createWriteStream(Path);
const ws = new WritableStream(output)
let blob = new Blob([res.data], {type: 'application/zip'})
const stream = blob.stream();
//optional
//stream.pipeTo(ws).then(console.log('Done!!!'));
stream.pipeTo(ws);
})
Solution 4:[4]
You must be added responseType
as AxiosRequestConfig not header
const response = await axios(`${url}/api/v1/rest/export`, {
method: 'POST',
responseType: 'stream',
headers: {
'Content-Type': 'application/json',
Authorization: authToken.includes('Bearer') ? authToken : `Bearer ${authToken}`,
},
data: query,
});
response.data.pipe(fs.createWriteStream('./export.csv'));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Kaizokupuffball |
Solution 2 | Gerd |
Solution 3 | EZEQUIEL MATIAS QUIROGA |
Solution 4 | Mohammad Fallah |