Search code examples
node.jsangularimageuploadmulter

Upload image and Json from Angular to Multer/Express


I would like to upload an image and a json to a server using Express and Multer. When I test with Postman there is no problem but when I test with the Front-end in Angular, it seems that the image isn't sent.

Here are the codes :

problem-form.component.html

<div class="problemContainer">
 <div class="problemForm">
  <h2>Soumission de problème</h2>
  <form [formGroup]="form" (ngSubmit)="submitForm()">
    <p>
      <mat-form-field class="inputFW">
        <input matInput formControlName="User" placeholder="Adresse email">
        <mat-error>This field is required</mat-error>
      </mat-form-field>
    </p>
    <p>
      <mat-form-field class="inputFW">
        <input matInput value="{{machineName}}" placeholder="Nom de la machine" disabled>
        <mat-error>Le nom de la machine est requis</mat-error>
      </mat-form-field>
    </p>
    <p>
      <mat-form-field class="inputFW">
        <textarea matInput placeholder="Description du problème (max 200 caractères)" formControlName="Description" rows="3"></textarea>
      </mat-form-field>
    </p>
    <p>
      <label>Image (Optionnel)</label><br><br>
      <input type="file" (change)="fileChange($event)" name="image" />
    </p>
    <button mat-raised-button color="primary">Envoyer</button>
  </form>
 </div>

function in the component that call the service

submitForm(){
  if(this.form.valid){
    let obj = this.form.value
    obj.image = this.image
    this.service.createProblem(obj).subscribe(data => console.log(data), err => {console.log(err)})
  }else{
    console.log("erreur")
  }
}

function in the service that post to the server

createProblem(problem: Object){
  console.log('roman')
  let form = new FormData()
  form.append('Name', problem['Name'])
  form.append('Description', problem['Description'])
  form.append('User', problem['User'])
  form.append('image', problem['image'])
  console.log(problem['image'])
  return this.http.post(getUrl()+ `problems`, form);
}

Configuration of multer

let storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'images')
  },
  filename: function (req, file, cb) {
    cb(null, 'problem_' + Date.now()+'.'+mime.extension(file.mimetype))
  }
})
let upload = multer({ storage: storage });

The route that call a function in the controller

router.route('/')
/** GET /api/problems - Get list of Problems */
  .get(pbCtrl.list)

/** POST /api/problem - create a new problem */
  .post(/*validate(paramValidation.problem), */upload.single('image'), pbCtrl.create);

The function in the controller

function create(req, res, next) {
  let photo
  if(req.file != null)
    photo = req.file.filename
  PC.findOne({ Name: req.body.Name, Active: true }, { '_id': 0 }).exec()
    .then((pc) => {
        if (pc == null)
            return res.sendStatus(400)
        const newPc = new PC({
            Name: pc.Name,
            Local: pc.Local,
            IP: pc.IP,
            MAC: pc.MAC,
            Comment: pc.Comment,
            Active: pc.Active,
            Problem: { User: req.body.User, Description: req.body.Description, Image: photo }
        })
        newPc.save()
            .then(savedPC => {
                res.json(savedPC);
                //return next();
            }).catch(e => { next(e); });;

    })
    .catch((err) => {
        console.log(err)
        res.sendStatus(400)
    })
}

Thanks all


Solution

  • Resolved

    function to load file

    fileChange($event) {
      let reader = new FileReader();
      if($event.target.files && $event.target.files.length > 0) {
        let file = $event.target.files[0];
        this.file = file
      }
    }
    

    function that submit the form

    submitForm(){
      if(this.form.valid){
        let obj = this.form.value
        obj.image = this.file
        this.service.createProblem(obj).subscribe(data =>     this.openSnackBar('Votre demande a bien été enregistrée'), err =>   {console.log(err)})
      }else{
        console.log("erreur")
      }
    }
    

    function in the service to post

    createProblem(problem: Object){
      let form = new FormData()
      form.append('Name', problem['Name'])
      form.append('Description', problem['Description'])
      form.append('User', problem['User'])
      form.append('image', problem['image'])
      return this.http.post(getUrl()+ `problems`, form).map((res) => {
        return res.json()
      });
    }