title: Angular to Node to Backend API - Multer file upload, req.file is undefined
body: <p>I have this setup in my application -</p>
  
  <p>angular 7 --> node server --> springboot API.</p>
  
  <p>There are some pages on the angular app that sends a json to the API. There are others that needs to send an uploaded image file. I'm unable to send the uploaded image to the node server and API. My code snippet is given below. In app.js, req.body and req.file are coming up as empty and undefined respectively. I looked through similar questions on the site, but couldn't get my code working. Where am I going wrong? Any help is much appreciated.</p>
  
  <pre><code>console.log(req.body); // form fields
  console.log(req.file); // form files
  </code></pre>
  
  <h2>Angular code</h2>
  
  <p>module.component.html</p>
  
  <pre><code>&lt;input type="file" name="file-to-upload" (change)="onFileChanged($event.target.files)"&gt;
  
  &lt;div style="margin-top: 20px;"&gt;
    &lt;button mat-raised-button type="button (click)="onSubmitCreateTemplate()"&gt;
      Submit
    &lt;/button&gt;
    &lt;button mat-raised-button color="primary" (click)="onCancel()"&gt;Cancel&lt;/button&gt;
        &lt;/div&gt;
  </code></pre>
  
  <p>module.component.ts</p>
  
  <pre><code>export class ModuleComponent implements OnInit {
    ...
  
    onFileChanged(files: FileList) {
        this.fileName = files.item(0);
    }
  
    public onSubmitCreateTemplate() {
      this.moduleService.createTemplate(
          this.receiptForm.value['merchantID'] === null ? '' : this.receiptForm.value['merchantID'],
          "some string",
          'Draft',
          this.fileName
      ).subscribe(
          ...
      );
    }
  </code></pre>
  
  <p>moduleService.ts</p>
  
  <pre><code>export class ModuleService {
      geHeaders() {
          const httpheaders = {
              headers: new HttpHeaders({
                  'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
              })
          };
          return httpheaders;
      }
  
      createTemplate(merchantId: string, template: string, templateStatus: string, logoImageFile: File) {
          let headerInfo = this.geHeaders();
          const url = `${this.receiptTemplateUrl}`;
  
          let formData = new FormData();
          formData.append('file-to-upload', logoImageFile, logoImageFile.name);
          return this.http.post(url, formData, headerInfo);
      }
  }
  </code></pre>
  
  <h2>Node Server</h2>
  
  <p>proxy-server.js</p>
  
  <pre><code>const express = require('express');
  const bodyParser = require('body-parser');
  const http = require('http');
  var multer = require("multer")
  var upload = multer();
  
  const app = express();
  const httpServer = http.createServer(app);
  
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: true }));
  
  // for parsing multipart/form-data
  app.use(upload.array());
  app.use(express.static('public'));
  
  const appRoute = require('./server/routes/app');
  app.use('/api', appRoute);
  
  const port = process.env.PORT || 3000;
  if (process.env.NODE_ENV === 'development') {
      httpServer.listen(port);
  } else {
      // for integration and production
      httpServer.listen(3000);
  }
  </code></pre>
  
  <p>app.js</p>
  
  <p>I don't want to save the file on disk, instead have to send it to the backend api. I tried saving on disk, just to see if the file is being saved. Unfortunately, file isn't being saved.</p>
  
  <pre><code>const express = require('express');
  const router = express.Router();
  const request = require('request');
  const { logger } = require('./../helpers/logger');
  const mposLogger = logger('mppp');
  var multer = require("multer")
      var storage = multer.diskStorage({
              destination: (req, file, cb) =&gt; {
              cb(null, 'uploads')
              },
              filename: (req, file, cb) =&gt; {
                  cb(null, file.fieldname + '-' + Date.now())
              }
      });
      var upload = multer({storage: storage});
     router.route('/:serviceName/admin/receipt').post(upload.single("file-to-upload"), function(req, res, next){
          console.log(req.body); // form fields
          console.log(req.file); // form files
      });
  
      router.all('/:serviceName/*', (req, res) =&gt; {
          ...
      });
  
      module.exports = router;
  </code></pre>
  
  <h2>API Backend on SpringBoot</h2>
  
  <pre><code>@RestController
  @RequestMapping("/admin")
  public class TemplateController extends AbstractController  {
  
      ...
  
      @RequestMapping(path="/receipt",method= RequestMethod.POST)
      public IResponse createTemplate(@RequestHeader Map&lt;String,String&gt; header,
                                 /*@Valid AddTemplateRequest request,*/
                                 @RequestParam("file") MultipartFile imageFile) throws GenericException {
  
    ...
    }
  </code></pre>
  
  <h2>Screenshot and Errors</h2>
  
  <p><a href="https://i.stack.imgur.com/3HRIb.png" rel="nofollow noreferrer">This is the form-data sent from the browser.</a></p>
  
  <p>On the node server end, console.log(req.file) prints 'undefined'.</p>