1

I need to use Axios to download files from a stream. I don't think it is a problem with the server because it works if i use the http package. This is the code i have:

export function downloadRequest (savePath, reqURL, currentFile, serverPath) {
  const file = fs.createWriteStream(savePath[0] + `/${currentFile}`)
  axios({
    method: 'get',
    url: `${storedIP}${reqURL}`,
    responseType: 'stream',
    headers: {
      Authorization: `Bearer ${token}`
    }
  }).then(function (reponse) {
    reponse.data.pipe(file)
    hashCheck(currentFile, savePath, serverPath)
  })

however this returns these two errors: the provided value 'stream' is not a valid enum value of type XMLHttpRequestResponseType. Uncaught (in promise) TypeError: reponse.data.pipe is not a function

I tried doing what is said in this post: Type error this.httpClient.get(...).pipe is not a function

But that made a windows popup saying something like this:

windows script host 

Script: c:\npm\node_modules\webpack\bin\webpack.js
Line: 1
Char: 1
Error: Invalid character
Code: 800A03F6
Source: Microsoft JScript compilation error

I went into that js file and Line 1 is #!/usr/bin/env node

I also tried uninstalling webpack and reinstalling but that didn't help.

Note: I am using Axios with quasar if that matters.

dragonbeast
  • 61
  • 2
  • 9
  • "I need to use Axios to download files from a stream" — Why? The error message suggests Axios doesn't support streams, and you said you had a working solution with the http module. – Quentin Dec 06 '19 at 19:05
  • Is this on the server, or are you using `electron` or something similar? – Marcos Casagrande Dec 06 '19 at 19:09
  • @Quentin well i guess i dont need to, I just like some of the feature that Axios has like: ``axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;`` And: ``onDownloadProgress allows handling of progress events for downloads`` alos in the docs it says: ``responseType indicates the type of data that the server will respond with options are: 'arraybuffer', 'document', 'json', 'text', 'stream' `` – dragonbeast Dec 06 '19 at 19:12
  • @MarcosCasagrande im using electron and quasar but this isnt on the server. The server is just normal nodejs but is running on another pc – dragonbeast Dec 06 '19 at 19:16
  • Check my answer. – Marcos Casagrande Dec 06 '19 at 19:26

2 Answers2

2

If you're using electron, you should set the adapter to http instead of XMLHttpRequest

axios.defaults.adapter = require('axios/lib/adapters/http');

If you're getting response.data.pipe is not a function it appears that you can only get response.data as a stream in the main thread:

https://github.com/axios/axios/issues/1474#issuecomment-380594110

ipcRenderer.send("downloadRequest"); // when downloadRequest is called

Main thread

app.on("ready", async () => {

 // other electron setup

 ipcMain.on("downloadRequest", (event, arg) => {
   // axios download code here
 });
});
Marcos Casagrande
  • 37,983
  • 8
  • 84
  • 98
  • That got rid of the ``the provided value 'stream' is not a valid enum value of type XMLHttpRequestResponseType.`` But the ``response.data.pipe(file) is not a function`` is still there – dragonbeast Dec 06 '19 at 19:40
  • Are you still using `responseType: 'stream'`? Because it should work. Show the exact stack trace. – Marcos Casagrande Dec 06 '19 at 19:45
  • yeah i still have the ``responseType: 'stream'``and Im confused, what you mean by a trace? – dragonbeast Dec 06 '19 at 19:49
  • The error, the exact error you're getting. Copy & paste the stack trace (the error shown in the console, with the lines and so on) – Marcos Casagrande Dec 06 '19 at 19:52
  • ok gotcha, this is what that says: ``` RESTrequests.js?d591:96 Uncaught (in promise) TypeError: response.data.pipe is not a function at eval (RESTrequests.js?d591:97) (anonymous) @ RESTrequests.js?d591:96 Promise.then (async) downloadRequest @ RESTrequests.js?d591:88 downloadFn @ Table.vue?a2a3:177 click @ Table.vue?bc0c:48 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6911 ``` – dragonbeast Dec 06 '19 at 19:54
  • It is weird. Is this happening during a test using jest or something?. `console.log(response.data)` and show the output. What version of `axios` do you have, because it should work. – Marcos Casagrande Dec 06 '19 at 20:03
  • ok so now im more confused. The error about ``stream`` not being a type is back. and the log of response.data is a bunch of diamonds and weird symbols. Axios version is "0.18.1" And im not sure what jest is. Sorry im new to this stuff – dragonbeast Dec 06 '19 at 20:18
  • Put your whole code, how you're requiring accions, how you're setting the adapter, and where you're calling the function. – Marcos Casagrande Dec 06 '19 at 20:25
  • ok. im going to put it in a pastebin because it is pretty big – dragonbeast Dec 06 '19 at 20:26
  • here is the link: https://pastebin.com/h4dBkV92 there is a lot of other garbage that i didnt include but i kept everything that had to do with axios. – dragonbeast Dec 06 '19 at 20:37
  • axios.defaults.adapter = require('axios/lib/adapters/http') should be at the top of the file, after you require axios. – Marcos Casagrande Dec 06 '19 at 20:41
  • that still didnt fix the issue. Should i try creating just a normal node js project and see if the problem is axios or quasar and electron? – dragonbeast Dec 06 '19 at 20:44
  • Im confused on this, so in ``src-electron/electron-main.js`` i put the ipcMain part, and then in the Table.vue i call the send part? – dragonbeast Dec 06 '19 at 21:25
  • Exactly, that's how you should do it. – Marcos Casagrande Dec 06 '19 at 21:44
-1

In electron version 9.0.4, no need of below line

axios.defaults.adapter = require('axios/lib/adapters/http');   

In Renderers

ipcRenderer.send("download_file");

In your Main use below code

ipcMain.on("download_file", (event, args) => {
        var url = "YourFileUrl";
    
        // console.log(data)
    
        require("axios").get(url, { responseType: 'stream' })
          .then(res => {
            var fileName = res.headers['content-disposition'].split("=")[1].split("\"")[0];
           
            const writer = require('fs').createWriteStream("Location to save the file");
    
            new Promise((resolve, reject) => {
    
              res.data.pipe(writer);
              let error = null;
    
              writer.on('error', err => {
                error = err;
                writer.close();
                reject(err);
              });
    
              writer.on('close', () => {
                if (!error) {
                  resolve(true);
                }
                //no need to call the reject here, as it will have been called in the
                //'error' stream;
              });
            });
          }).catch((error) => {
            console.log(error)
          });    
      }

);

Reference :

node.js axios download file and writeFile

DevXtranet
  • 39
  • 3