title: How to download an excel (xlsx) file using Angular 5 HttpClient get method with Node/Express backend?
body: <p>I have an excel file in a directory on my nodejs server - Path to the file is - ./api/uploads/appsecuritydesign/output/appsecdesign.xlsx</p>
  
  <p>On click of a button in my Angular 5 component I am just trying to download the file using FileSaver. </p>
  
  <p>Below is my Angular component.</p>
  
  <p><a href="https://i.stack.imgur.com/bpQ5X.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bpQ5X.png" alt="Angular Component with Download button"></a></p>
  
  <p>Here the template code for the button in Angular that will call the saveFile() function once clicked.</p>
  
  <pre><code>&lt;a class="btn btn-primary" (click) = "saveFile()"&gt;Download&lt;/a&gt;
  </code></pre>
  
  <p>Here is the saveFile() function.</p>
  
  <pre><code>   saveFile(){
  
      console.log("In ToolInput Component: ", this.token); //Okta token
            console.log("In ToolInput Component: ", this.whatamidoing); //this variable has the server FilePath
  
  this.fileService.getappsecdesignfile(this.token, this.whatamidoing).subscribe(res =&gt; {
              let blobtool5 = new Blob([res], { type: 'application/vnd.ms-excel;charset=utf-8' });
              FileSaver.saveAs(blobtool5, 'Application_Security_Design.xlsx');
            },
            (err: HttpErrorResponse) =&gt; {
              if (err.error instanceof Error) {
  
                    console.log('An error occurred:', err.error.message);
                    console.log('Status', err.status);
                  } else {
                    console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
                    console.log('Status', err.status);
                  }
            });
      }
  </code></pre>
  
  <p>At this point I checked the console.log in the browser. They are exactly what they are supposed to be. So I am passing the correct filepath and token to getappsecdesignfile method in my fileService. </p>
  
  <p><a href="https://i.stack.imgur.com/1ViXO.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1ViXO.png" alt="enter image description here"></a></p>
  
  <p>Now Lets take a look at the getappsecdesignfile method in my fileService.</p>
  
  <pre><code>getappsecdesignfile ( token, tool5filepath ) : Observable&lt;any&gt;{
  
         console.log("In Service tool5filepath: ", tool5filepath);
         console.log("In Service token", token);
         console.log("In Service GET url: ", this.getappsecdesignfileurl);
  
         //Since the tool5filepath has / (slashes etc) I am encoding it below.
  
         let encodedtool5filepath = encodeURIComponent(tool5filepath);
         console.log('Encoded File Path: ', encodedtool5filepath);
  
         let req = new HttpRequest('GET', this.getappsecdesignfileurl,{params: new HttpParams().set('path', encodedtool5filepath)},{headers: new HttpHeaders().set('Accept', 'application/vnd.ms-excel').set('Authorization', token)});
         console.log(req);
         return this.http.request(req);
  
     }
  </code></pre>
  
  <p>That's all there is to the fileService method. Lets look at the console.logs from this method from the browser to ensure all the correct values are being set.</p>
  
  <p><a href="https://i.stack.imgur.com/Kyyu8.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Kyyu8.png" alt="enter image description here"></a></p>
  
  <p>Now Lets take a look at the request itself before we go to the server part.</p>
  
  <p><a href="https://i.stack.imgur.com/WrsBB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/WrsBB.png" alt="enter image description here"></a></p>
  
  <p>As far as I am concerned the headers are set correctly, params are set correctly. Two issues I see is that Angular's interceptors probably sets the responseType: json and adds a param op:s to my request.</p>
  
  <p>Node/Express Server code.</p>
  
  <pre><code>app.get('/getappsecdesignfile', function(req, res){
  console.log("In get method app security design");
      accessTokenString = req.headers.authorization;
      console.log("Okta Auth Token:", accessTokenString);
  
      console.log("Tool5 File Path from received from Angular: ", req.query.path); //this is where the server console logs shows Tool5 File Path after decoding: ./undefined
  
      oktaJwtVerifier.verifyAccessToken(accessTokenString)
      .then(jwt =&gt; {
      // the token is valid
        console.log(jwt.claims);
  
        res.setHeader('Content-Disposition', 'attachment; filename= + Application_Security_Design.xlsx');
        res.setHeader('Content-Type', 'application/vnd.ms-excel');
  
        let tool5filepath = './' + decodeURIComponent(req.query.path);
        console.log("Tool5 File Path after decoding: ", tool5filepath);
        res.download(tool5filepath);
  
        }).catch(err =&gt; {
          // a validation failed, inspect the error
          res.json({success : false, message : 'Authorization error.'});
        });
      });
  </code></pre>
  
  <p>If I use Postman the api works fine. However somewhere between Angular to Node communication something happens that I don't understand.</p>
  
  <p>Below is what the server logs. (Big question how does this become undefined)?</p>
  
  <pre><code>Tool5 File Path from received from Angular:  undefined
  Tool5 File Path after decoding:  ./undefined
  Error: ENOENT: no such file or directory, stat '&lt;dirpath&gt;/undefined'
  </code></pre>
  
  <p>Here is what I see in the browser log:</p>
  
  <pre><code>zone.js:2933 GET http://localhost:3000/getappsecdesignfile 404 (Not Found)
  toolinput.component.ts:137 Backend returned code 404, body was: &lt;!DOCTYPE html&gt;
  &lt;html lang="en"&gt;
  &lt;head&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;title&gt;Error&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;pre&gt;Error: ENOENT: no such file or directory, stat &amp;#39;&lt;dirpath&gt;/undefined&amp;#39;&lt;/pre&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>Then the browser downloads a xlsx file that is corrupt and cannot be opened.</p>
  
  <p>I have checked the file resides in the directory and is ready to be downloaded.</p>
  
  <p><a href="https://i.stack.imgur.com/mhsUP.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/mhsUP.png" alt="enter image description here"></a></p>
  
  <p>Thanks for any tips that can help me resolve this issue.</p>