How to Upload a File in Angular 4
angular2 file upload tutorial angular two upload file to server angular 2 file upload component angular 4 file upload angular2-image-upload example angular 2 paradigm gallery example ng2 file upload formdata ng2 file upload additionalparameter angular2 multipart/form-information postal service
Upload file with information by clicking on button or by elevate and drop, is the topic of this article. We will try to create an epitome gallery by uploading files and save data into database and images into a folder. Nosotros will attempt to create a component in a way that it tin can be used anywhere in entire application and configure properties like file size, type of files, single or multiple files, maximum number of files a user can upload at a time.
Create Athwart 4 CLI application by using
ng new ImageGallery --ng4 Open Package.json and add bootstrap to design this project:
"bootstrap": "^iii.3.7" // Open ImageGallery folder and run npm install // Open up Angular-cli.json file and add together in styles "styles": [ "styles.css", "../node_modules/bootstrap/dist/css/bootstrap.min.css" ], Let'south see nosotros want to give the feature to configure the control for different validation similar
- Number of files
- File Extensions to exist uploaded
- Maximum size of a file
At the aforementioned fourth dimension we want to pass some values, considering when we volition be uploading a file it should exist linked with some records, for this say we want to utilise the projection Id and Department Id, we can use any number of parameters
- Project Id
- Department Id
Create a new component names FileUpload.Component by using control:
ng generate component FileUpload Open file file-upload.component.html and add following code in it
<div draggable="truthful" ngClass="{{dragAreaClass}}"> <div class="row"> <div course="col-doctor-12 text-eye" > <a href="javascript:void(0)" (click)="file.click()" > Click to browse </a> Or Drag & Driblet to upload your files <input type="file" #file [multiple]="(maxFiles > i)" (alter) = "onFileChange($event)" mode="display:none" /> </div> </div> </div> <div class="row mistake" *ngIf="errors.length > 0"> <ul> <li *ngFor="let err of errors">{{err}}</li> </ul> </div> This the unabridged html to make a component to upload file past clicking and past drag and drib.
Allow'southward see what this code is:
- draggable="true": make this div drag and dropable
- ngClass="{{dragAreaClass}}": utilise class to change look and feel when employ move file at the time of drag and driblet
- Given a reference proper name to the input #file. On clicking the button nosotros are calling the click event of input type file.
- (click)="file.click()": to click the browse push button by plan because we don't want to testify the button
- Come across there is input type file which is used to open the browse file just set property display: none to hide it.
- [multiple]="(maxFiles > 1)": configurable, if max file to upload is more than i means user tin can upload multiple files otherwise simply one file at a time.
- (modify) = "onFileChange($upshot)": When user will click and browse and select a file, this method volition be called to validate and upload the files.
- Next we used ngFor to show the listing of error while uploading the file, it volition bear witness all the errors like max number of file allowed, file extension, file size etc.
file-upload.component.ts
We will see this file function by office, open up this file and beginning import some decorators:
import { Component, OnInit, Input, Output, EventEmitter, HostListener } from '@athwart/core'; import {FileService} from '../../services/file.service'; @Component({ selector: 'app-file-upload', templateUrl: './file-upload.component.html' }) We imported here everything we need to use for drag and drib, input parameter, output to notify the user the status of upload and register different listeners for drag and drop.
We demand some variable for our upload component which nosotros are going to add at the start of the grade:
export course FileUploadComponent implements OnInit { errors: Array<string> =[]; dragAreaClass: string = 'dragarea'; @Input() projectId: number = 0; @Input() sectionId: number = 0; @Input() fileExt: string = "JPG, GIF, PNG"; @Input() maxFiles: number = 5; @Input() maxSize: number = v; // 5MB @Output() uploadStatus = new EventEmitter(); constructor(individual fileService: FileService) { } ngOnInit() { } .......... } Let's see why nosotros need these variables, @Input is used to configure the component different properlies and @output to emit the upload status:
- errors: List of error to show during upload
- dragAreaClass: to change await and feel for upload area
- projectId, sectionId: to save extra data for project id if any otherwise 0
- fileExt: what type of file you desire to apply this component, default it will accept images with extension jpg, gif, png, it is not instance sensitive
- maxFiles: How many files a user can upload at a time, default is 5
- maxSize: What should exist the max file size allowed to upload, it is per file and non the total size when uploading multiple files, default is 5 MB
- uploadStatus: event emitter to the page where we will use this component and give the status of upload, true or simulated, you can alter according to your requirements
- In constructor, we declare the object of our FileService to upload the file by using the Spider web API method which nosotros volition create latter.
Add the method file change to upload the file on clicking and selecting the file, we already added this method proper name in our html onFileChange($result)
onFileChange(event){ let files = effect.target.files; this.saveFiles(files); } For now don't worry about the this.saveFiles method, we will add information technology latter in this article.
Now we will add different methods for drag and drib: onDragOver: add this method to modify the css form when user drag over to drib area
@HostListener('dragover', ['$result']) onDragOver(consequence) { this.dragAreaClass = "droparea"; event.preventDefault(); } onDragEnter: add this method to modify the css course when user enter to driblet area
@HostListener('dragenter', ['$event']) onDragEnter(event) { this.dragAreaClass = "droparea"; event.preventDefault(); } onDragEnd: add this method to change the css class, it is called when elevate operation is beingness ended
@HostListener('dragend', ['$outcome']) onDragEnd(result) { this.dragAreaClass = "dragarea"; outcome.preventDefault(); } onDragLeave: add this method to alter the css class, it is chosen when goes out of the drag and driblet area, so demand to change the area to normal now.
@HostListener('dragleave', ['$consequence']) onDragLeave(result) { this.dragAreaClass = "dragarea"; event.preventDefault(); } onDrop: This is the event which is chosen when user driblet files to our drag and drib area and now nosotros need to bank check the dropped files and call the save method to save files
@HostListener('drop', ['$event']) onDrop(outcome) { this.dragAreaClass = "dragarea"; event.preventDefault(); issue.stopPropagation(); var files = consequence.dataTransfer.files; this.saveFiles(files); } Annotation: In all our drag & drop events we use the preventDefault, information technology is important otherwise file will endeavor to open up in the browser.
Salve File method, we used here because in both type of upload, either past clicking and selecting or by drag and drop instance we employ the same method to upload the files:
saveFiles(files){ this.errors = []; // Clear mistake // Validate file size and allowed extensions if (files.length > 0 && (!this.isValidFiles(files))) { this.uploadStatus.emit(faux); return; } if (files.length > 0) { let formData: FormData = new FormData(); for (var j = 0; j < files.length; j++) { formData.suspend("file[]", files[j], files[j].name); } var parameters = { projectId: this.projectId, sectionId: this.sectionId } this.fileService.upload(formData, parameters) .subscribe( success => { this.uploadStatus.emit(truthful); console.log(success) }, mistake => { this.uploadStatus.emit(true); this.errors.push(error.ExceptionMessage); }) } } This function of the code is master to upload the file with data, what this lawmaking will do:
- First of all it volition clear the error if there are whatever previous fault
- Check number of files and other validation which we will see adjacent
- If anything goes invalid, it volition return, show the error, and notify the parent page past using uploadStatus emitter
- If all goes well, try to add files to FormData information every bit an array
- Create a variable
parametersto pass actress data to the Service/Web API - Call our service
uploadmethod to upload files - Notify the status of upload to parent page
isValidFiles: This method will check the unlike types of validations like extension, size and number of files:
private isValidFiles(files){ // Bank check Number of files if (files.length > this.maxFiles) { this.errors.push("Error: At a time you tin upload only " + this.maxFiles + " files"); return; } this.isValidFileExtension(files); render this.errors.length === 0; } Encounter first we cheque the number of files to upload is greater to the number of files allowed, then nosotros use another method isValidFileExtension which bank check every file extension
private isValidFileExtension(files){ // Make assortment of file extensions var extensions = (this.fileExt.split up(',')) .map(function (10) { return x.toLocaleUpperCase().trim() }); for (var i = 0; i < files.length; i++) { // Get file extension var ext = files[i].name.toUpperCase().split up('.').pop() || files[i].name; // Bank check the extension exists var exists = extensions.includes(ext); if (!exists) { this.errors.push("Error (Extension): " + files[i].proper name); } // Cheque file size this.isValidFileSize(files[i]); } } First we converted the fileExt string to an array and then catechumen to lower example and and so keep checking one by ane all the file extensions. At the terminate we call another method isValidFileSize which will check for the file size
individual isValidFileSize(file) { var fileSizeinMB = file.size / (1024 * 1000); var size = Math.circular(fileSizeinMB * 100) / 100; // convert upto two decimal place if (size > this.maxSize) this.errors.push("Error (File Size): " + file.name + ": exceed file size limit of " + this.maxSize + "MB ( " + size + "MB )"); } Before writing the service code in Angular, let's add Web API lawmaking first then we can come dorsum and complete our service code.
We will upload the file in a folder and save record into database, here is the list of properties we will save into database, and so create a table named "Files":
CREATE TABLE [Files]( [Id] [int] Not Naught PRIMARY Cardinal IDENTITY(1,1), [FileName] [varchar](200) NOT NULL, [FileSize] [int] NOT NULL, [ImagePath] [varchar](200) Non NULL, [ThumbPath] [varchar](200) Non Cypher, [ProjectId] [int] NOT Cipher, [SectionId] [int] Not Cypher ) Here the complete code in Spider web API to save the file into folder every bit well every bit save into database
[HttpPost] public async Task<HttpResponseMessage> Upload(int projectId, int sectionId) { var status = new MyReponse(); endeavor { var context = HttpContext.Electric current.Request; if (context.Files.Count > 0) { var filesReadToProvider = await Request.Content.ReadAsMultipartAsync(); var index = 0; foreach (var streamContent in filesReadToProvider.Contents) { var fileBytes = wait streamContent.ReadAsByteArrayAsync(); var file = new File(); file.ProjectId = projectId; file.SectionId = sectionId; file.FileName = context.Files[alphabetize].FileName; file.FileSize = fileBytes.Length; file.ImagePath = Cord.Format("/UploadedFiles/{0}_{ane}_{2}", projectId, sectionId, file.FileName); file.ThumbPath = String.Format("/UploadedFiles/{0}_{1}_th_{2}", projectId, sectionId, file.FileName); var img = Paradigm.FromStream(new System.IO.MemoryStream(fileBytes)); look SaveFiles(file, img); alphabetize++; } condition.Status = true; status.Message = "File uploaded successfully"; return Request.CreateResponse(HttpStatusCode.OK, status); } } grab (Exception ex) { status.Message = ex.Message; } return Request.CreateResponse(HttpStatusCode.OK, condition); } Let's come across this lawmaking and explanation
- Accept 2 parameter projection id and section id, you can add together as many as yous want
- Check the number of files by using request, if at that place is any file, read it and save information technology
- Loop through and keep saving one by one
- Create file entity to save into database
- convert file bytes into prototype to save
- await SaveFiles(file, img): this is the method which save files two size 200 x 200 equally thumbnail and 600 x 600 and salvage into a binder and finally relieve path and other detail into database.
I volition upload this Web API file on github so you can easily create your Web API method.
To use this Spider web API method we demand a service so create a folder "services" in src binder and create a service named FileService past using command:
ng generate service File Add post-obit code in it to save the file and get the uploaded file detail:
import { Injectable } from '@angular/core'; import { Http, Headers, RequestOptions } from '@athwart/http'; import { Appreciable } from 'rxjs/Rx'; import 'rxjs/add together/operator/map'; import 'rxjs/add/operator/take hold of'; @Injectable() consign class FileService { _baseURL: string = 'http://localhost:xxxx/api/fileupload/' constructor(individual http: Http) { } upload(files, parameters){ allow headers = new Headers(); let options = new RequestOptions({ headers: headers }); options.params = parameters; return this.http.post(this._baseURL + 'upload', files, options) .map(response => response.json()) .catch(mistake => Observable.throw(error)); } getImages(){ return this.http.go(this._baseURL + "getimages") .map(response => response.json()) .grab(mistake => Observable.throw(fault)); } } It has two method upload and getImages, allow see these ii methods in particular:
- upload method take two parameters files and extra parameters to save into database
- Not I apply the header to pass these extra parameters
- Nosotros use here Http Post Method to save the files
- Send files in body
- Actress parameters are transport via header
- getImages is just retrieving all the files from database
We are done, let's add this component to the app.component.html to upload the file and use some hard coded value for projection id and section id:
<div form="row"> <div class="col-medico-12"> <app-file-upload projectId="100" sectionId="107" maxFiles="4" maxSize="2" fileExt="JPG, GIF, PNG" (uploadStatus)="refreshImages($effect)" > </app-file-upload> </div> </div> As you can see hither everything is configurable so this component tin be used for any number of files, whatever size of file, whatsoever type of files.
We use here refreshImages method to chech the upload status and refresh the images on the page.
refreshImages(condition){ if (status == truthful){ panel.log( "Uploaded successfully!"); this.getImageData(); } } How to prove the images on the page
<div class="well"> <img *ngFor="let img of images" [src]="'http://localhost:xxxx' + img.thumbPath" grade="img-thumbnail" alt=""> </div> In app.component.ts add code to become images getImageData() from the database past using Web API method, call this method OnInit and when we get notification from upload component that upload completed:
import { Component, OnInit } from '@athwart/core'; import { FileService } from '../services/file.service'; @Component({....}) export class AppComponent implements OnInit { .... constructor(individual fileService: FileService) { } ngOnInit(){ this.getImageData(); } getImageData(){ this.fileService.getImages().subscribe( data =>{ this.images = data.result}, error => this.errorMessage = error ) } ...... } CSS used for this elevate and drop and error:
.mistake{ colour: #f00; } .dragarea{ font-size: 24px; edge: 3px solid #bbb; padding: 20px ; background-color: #fff; color: #bbb; } .droparea{ font-size: 24px; edge: 3px dashed #bbb; padding: 20px ; background-colour: #eff; color: #aaa; } But uploaded the src folder from my Paradigm Gallery application to github - please download from in that location for more detail, likewise added complete Web API controller with name FileUploadController.cs, hope information technology will help to sympathize both part.
Source: http://www.advancesharp.com/blog/1218/angular-4-upload-files-with-data-and-web-api-by-drag-drop
0 Response to "How to Upload a File in Angular 4"
Post a Comment