1

Please, I am using multer middleware for file upload in angular mean stack. I can't get req.file but can get req.body meaning the file is not being upload. At first when I upload I check the designated upload folder and I can't see anything but other text data can enter the mongoose database.

I then tried to res.send(req.file.filename) it says could not find property 'filename' of undefined. When I res.send(req.file) it returns null. but when I res.send(req.body) it returns the textual data keyed in from the html form. What have I done wrong?

I have gone through many suggestions to similar problem here on stackoverflow and other places online but none solved the problem for me.

Pls help

Find my code in vehicle.route.js below:

  path = require('path'),
  multer = require('multer'),

  app = express();

  const DIR = '../uploads/';
  const storage = multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, DIR);
    },
    filename: (req, file, cb) => {
      const fileName = file.fieldname + '-' + Date.now();
      cb(null, fileName)
    }
  });

  let upload = multer({ 
    storage: storage
  })

vehicleRouter = express.Router();

// Vehicle model
let Vehicle = require('../models/Vehicle');

app.use(express.static(path.join(__dirname, '../uploads')));


// Get All Employees
vehicleRouter.route('/').get((req, res, next) => {
  Vehicle.find((error, data) => {
    if (error) {
      return next(error)
    } else {
      res.json(data)
    }
  })
})



vehicleRouter.post('/register', upload.single('purchaseReceipt'), (req, res, next) => {
  res.json(req.file.filename)
  return;

/*vehicleRouter.post('/register', upload.single('purchaseReceipt'), (req, res, next) => {
  res.json(req.file)
  return;
  const vehicle = new Vehicle({
    fullName: req.body.fullName,
    purchaseReceipt: req.file.filename
  });
  vehicle.save().then(result => {
    console.log(result);
    res.status(201).json({
      message: "Vehicle registered successfully!",
      userCreated: {
        _id: result._id,
        name: result.name,
        purchaseReceipt: result.purchaseReceipt
      }
    })
  })

  /*Vehicle.create(req.body, (error, data) => {
    if (error) {
      return next(error)
    } else {
      res.json(data)
    }
  })*/

  //res.json('from register vehicle')
  })

  app.use(express.static(path.join(__dirname, './uploads')));
module.exports = vehicleRouter;```

I tried uploading straight but it isnt then I commented part of the code and tried to send back req.file.filename as response but it is saying: error: "Cannot read property 'filename' of undefined"

[the error code on console][1]


  [1]: https://i.sstatic.net/LY9ob.png


vehicle-registration.component.html code ie the html form
```<div class="card">
  <div class="card-body">
    <form method="post" [formGroup]="vehicleForm" (ngSubmit)="onSubmit()" enctype="multipart/form-data">
      <div class="form-group">
        <label class="col-md-4">Full Name</label>
        <input type="text" class="form-control" formControlName="fullName" />
      </div>

      <div class="form-group">
        <div class="preview" *ngIf="preview && preview !== null">
          <img [src]="preview" [alt]="vehicleForm.value.name">
        </div>
      </div>

      <!--<div class="form-group">
        <label class="col-md-4">Upload Purchase Receipt</label>
        <input type="text" class="form-control" formControlName="purchaseReceipt" />
      </div>-->
      <div class="form-group">
        <label class="col-md-4">Upload Purchase Receipt </label>
        <input type="file" class="form-control"  (change)="uploadFile($event)" formControlName="purchaseReceipt" name="purchaseReceipt"/>
      </div>

      <div class="form-group">
        <div class="row">
          <div class="col-sm-3">
              <button class="btn btn-success btn-sm btn-block" type="submit">Register Vehicle</button>
          </div>
        </div>
        </div>

    </form>
  </div>
</div>```


vehicle-registration.component.ts code

import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { VehicleService } from '../../service/vehicle.service';

@Component({ selector: 'app-vehicle-registration', templateUrl: './vehicle-registration.component.html', styleUrls: ['./vehicle-registration.component.css'] }) export class VehicleRegistrationComponent implements OnInit { preview: string; vehicleForm: FormGroup;

constructor(public fb: FormBuilder, private vs: VehicleService) { this.createForm() }

ngOnInit() { }

createForm() { this.vehicleForm = this.fb.group({ fullName: ['', [Validators.required]], purchaseReceipt: [null, [Validators.required]], }); }

uploadFile(event) { const file = (event.target as HTMLInputElement).files[0]; this.vehicleForm.patchValue({ avatar: file }); this.vehicleForm.get('avatar') // .updateValueAndValidity()

// File Preview
const reader = new FileReader();
reader.onload = () => {
  this.preview = reader.result as string;
}
reader.readAsDataURL(file)

}

onSubmit() { if (!this.vehicleForm.valid) { return false; } else { this.vs.registerVehicle(this.vehicleForm.value) .subscribe( (res) => { console.log('Vehicle successfully registered!'); console.log(res); }, (error) => { console.log(error); } ); } }

}```

The service file ie vehicle.service.ts

import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})
export class VehicleService {

  baseUri: string = 'http://localhost:3000/vehicle';
  headers = new HttpHeaders().set('Content-Type', 'application/json');

  constructor(private http: HttpClient) { }

  registerVehicle(data): Observable<any>{
    console.log(data);
    const url = `${this.baseUri}/register`;
    return this.http.post(url, data);
  }

}```

1
  • Hi, Did you get any solution ? Commented Jan 12, 2021 at 19:20

1 Answer 1

0

Hello can you post your angular code so we see if you are actually sending the file to the backend - nodejs. thanks and waiting

new update!!

sorry i made a mistake wisdom. i am supposed to set the form data use a formdata.set.... inside where you used the..

let image = new fileReader();
formdata: Formdata = new Formdata();  //updated!!

constructor(){}

preview($event){
this.image.onloadend = ()=>{
    //other codes
    this.formdata.set("image", $event.target.files[0]); // you can use this.formdata.append(...) if you want, but append keeps adding if maybe there is a retry due to error
}

this.image.readAsDataURL($event.target.files[0]);

}





onsubmit(){


//append or set other thing

this.vs.registerVehicle(this.formdata).subscribe(d=>{
// code here
})


}



using formData while uploading an image makes it easier to receive the file at the backend.

Sign up to request clarification or add additional context in comments.

2 Comments

my vehicle-registration.component.html code ie the html form:
I have this error: TypeError: Cannot read property 'set' of undefined. and it is pointing to the line of code where I wrote: this.formdata.set('purchaseReceipt', this.vehicleForm.value); I also declared formdata: FormData inside the class

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.