web-dev-qa-db-fra.com

Enregistrer FormData avec le téléchargement de fichier dans Angular 5

J'essaie de sauvegarder des fichiers avec FormData dans Angular 5 . Je peux obtenir le fichier unique, mais je ne sais pas comment faire pour télécharger tous les fichiers. , essayé de chercher des exemples. Mais seulement obtenu pour les téléchargements de fichiers multiples . Je veux télécharger chaque fichier à partir de ce formulaire.

Ci-dessous mon code:

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { Location } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
import { Category } from '../../../shared/services/categories/category';
import { CategoriesService } from '../../../shared/services/categories/categories.service';

@Component({
  selector: 'app-add-category',
  templateUrl: './add-category.component.html',
  styleUrls: ['./add-category.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class AddCategoryComponent implements OnInit {
  
  category: Category = new Category();
  fileToUpload: File = null;
  
  constructor(
    private categoriesService: CategoriesService,
    private route: ActivatedRoute,
    private location: Location  
  ) { }

  ngOnInit() {
  }

  goBack(): void {
    this.location.back();
  }

  handleFileInput(files: FileList) {
    console.log(files);
  }

  addCategory() {
    console.log(this.category);
    this.categoriesService.createCategory(this.category).subscribe(() => this.goBack());
  }

}
          <h3 class="box-title">Category</h3>

        <form role="form" (ngSubmit)="addCategory()" #categoryForm="ngForm">

              <div class="box-body">

                <div class="row">
                  <div class="col-lg-6">
                  <label for="Category Name">Name</label>
                  <input type="text" class="form-control" [(ngModel)]="category.category_name" name="category_name" id="category_name" placeholder="Enter Category Name" required="">
                </div>

                <div class="col-lg-6">
                  <label for="Category Path">Path</label>
                  <input type="text" class="form-control" [(ngModel)]="category.category_path" name="category_path" id="category_path" required="">
                </div>
              </div>
            </div>
            <br/>

            <div class="form-group">
                  <label for="Category Description">Description</label>
                  <textarea rows="3" [(ngModel)]="category.category_description" name="category_description" id="category_description" class="form-control" required=""></textarea>
            </div>
                
            <div class="col-lg-12 text-center">
                <input type="file" [(ngModel)]="category.category_banner" (change)="handleFileInput($event.target.files)" class="custom-file-input" name="category_banner" id="category_banner">
                <label class="custom-file-label" for="customFile">Banner</label>
            </div>
            <br/>

            <div class="form-group">
              <label for="Category Banner Code">Banner Code</label>
              <textarea rows="3" [(ngModel)]="category.category_banner_code" name="category_banner_code" id="category_banner_code" class="form-control" required=""></textarea>
            </div>
            
            <br/>
            
            <div class="col-lg-12">
                <input type="file" [(ngModel)]="category.category_image" (change)="handleFileInput($event.target.files)" class="custom-file-input" name="category_image" id="category_image">
                <label class="custom-file-label" for="customFile">Image</label>
            </div>
        
            <br/>

            <div class="col-lg-12">
                <input type="file" [(ngModel)]="category.category_icon" (change)="handleFileInput($event.target.files)" class="custom-file-input" name="category_icon" id="category_icon">
                <label class="custom-file-label" for="customFile">Icon</label>
            </div>

              <div class="form-group">
              <label for="Category Meta Title">Meta Title</label>
              <input type="text" [(ngModel)]="category.category_meta_title" class="form-control" name="category_meta_title" id="category_meta_title" placeholder="Enter Meta Title" required="">
            </div>

            <div class="form-group">
              <label for="Category Meta Description">Meta Description</label>
              <input type="text" [(ngModel)]="category.category_meta_decription" class="form-control" id="category_meta_description" name="category_meta_description" placeholder="Enter Meta Description" required="">
            </div>

            <div class="form-group">
              <label for="Category Meta Keyword">Meta Keyword</label>
              <input type="text" [(ngModel)]="category.category_meta_keyword" class="form-control" id="category_meta_keyword" name="category_meta_keyword" placeholder="Enter Meta Keyword" required="">
            </div>

            <div class="form-group">
             
              <div class="row">
                 <div class="col">Featured :</div>
                <div class="col">
                <label class="radio-inline" for="Category Featured">
                  <input type="radio" [(ngModel)]="category.category_featured" name="category_featured" id="category_featured" value="1" required="">Yes
                </label>
              </div>

              <div class="col">
                <label class="radio-inline" for="Category Featured">
                  <input type="radio" [(ngModel)]="category.category_featured" name="category_featured" id="category_featured" value="0" required="">No
                </label>
            </div>
            </div>
            </div>
              
            <input type="hidden" [(ngModel)]="category.category_status" name="category_status" id="category_status" value="1">

              <div class="box-footer col-md-12">
                <button type="submit" class="btn btn-primary">Submit</button>
              </div>
            </form>

1
Kamlesh Katpara

Voici ce que j'ai essayé et cela a fonctionné comme prévu:

handleCategoryBanner(files: FileList) {
    this.category.category_banner = '/categories/download/' + files[0].name;
    this.formData.append('category_banner', files[0], files[0].name);
    this.categoryContainersService.uploadFile(this.formData).subscribe(filename => console.log(files[0].name));
  }
<div class="col-lg-12 text-center">
        <input type="file" (change)="handleCategoryBanner($event.target.files)" class="custom-file-input" id="category_banner" accept=".jpeg,.png,.jpg">
        <input type="hidden" name="category_banner" [(ngModel)]="category.category_banner" />
        <label class="custom-file-label" for="customFile">Banner</label>
    </div>

2
Kamlesh Katpara

J'ai récemment eu un problème similaire. Ce problème peut être résolu en définissant le type de contenu de l'en-tête sur null dans le code Angular . Attacher l'extrait de code de Angular5 et du backend de démarrage à ressort.

let headers = new HttpHeaders();
//this is the important step. You need to set content type as null
headers.set('Content-Type', null);
headers.set('Accept', "multipart/form-data");
let params = new HttpParams();
const formData: FormData = new FormData();
for (let i = 0; i < this.filesList.length; i++) {
  formData.append('fileArray', this.filesList[i], this.filesList[i].name);
} 
formData.append('param1', this.param1);
formData.append('param2', this.param2);
this.http.post(this.ROOT_URL + this.SERVICE_ENDPOINT, formData, { params, headers }).subscribe((res) => {
    console.log(res);
});



In the spring boot backend, you need to have the controller as - 

@RequestMapping(value = "/uploadAndSendEmail", method = RequestMethod.POST, consumes= "multipart/form-data")    
public ResponseEntity<String> uploadAndSendEmail(@RequestParam("fileArray") MultipartFile[] fileArray, 
        @RequestParam(value = "param1", required = false) String param1,
        @RequestParam(value = "param2", required = false) String param2) {
        //do your logic
        }
3

Voici comment je gère plusieurs fichiers à partir d'une entrée de fichier unique . Mon composant collecte les données de formulaire et génère un objet Data, qui ne contient pas les fichiers. Il appelle ensuite cette méthode de service avec l'objet Data et les fichiers, qui envoient les données et les fichiers dans une publication en plusieurs parties.

  save(data: Data, filesForUpload: File[]): Observable<Data> {
    const formData = new FormData();

    // add the files
    if (filesForUpload && filesForUpload.length) {
      filesForUpload.forEach(file => formData.append('files', file));
    }

    // add the data object
    formData.append('data', new Blob([JSON.stringify(data)], {type: 'application/json'}));

    return this.http.post<Data>(this.apiUrl, formData);
  }

Donc, pour gérer deux entrées de fichier, vous pouvez faire ceci:

 save(data: Data, filesA: File[], filesB: File[]): Observable<Data> {
    const formData = new FormData();

    // add the files
    if (filesA && filesA.length) {
      filesA.forEach(file => formData.append('filesA', file));
    }

    if (filesB && filesB.length) {
      filesB.forEach(file => formData.append('filesB', file));
    }

    // add the data object
    formData.append('data', new Blob([JSON.stringify(data)], {type: 'application/json'}));

    return this.http.post<Data>(this.apiUrl, formData);
  }

Ce qui vous donnerait trois parties dans votre publication multipartie, une pour chaque ensemble de fichiers et une pour l'objet de données.

0
GreyBeardedGeek

il suffit de mettre l'attribut 'multiple' sur votre balise d'entrée.

 <div class="form-group">
    <label for="file">Choose File</label>
    <input type="file" id="file" (change)="handleFileInput($event.target.files)" multiple>
</div>
0
Ehsan Sadeghi