Angular File Upload Tutorial with Example

Welcome to our Angular File Upload Tutorial. We often need to upload files to our servers from web clients. This could be profile pictures, documents, or any other files. Today we’ll look at how we can do that using Angular.

Sending files to the server usually involves sending an HTTP POST multipart request. In a multipart request, the Content-Type header is set to multipart/form-data, and files are delimited by optional boundary parameters. The actual file is sent as a binary block of data.

This is slightly different than a regular REST post requests where the Content-Type header is usually set to application/json.

So let’s dive into the code, we’re starting with a blank angular project with bootstrap for styling.

Import the HttpModule in app.module.ts

We’ll need the following imports in the App Module for the next steps to work.

@NgModule({
 declarations: [
   AppComponent
 ],
 imports: [
   BrowserModule,
   AppRoutingModule,
   FormsModule, // required for input file change detection
   ReactiveFormsModule,
   HttpClientModule, // this is required for the actual http request
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }

Make upload button and change event in app.component.html

<div class="container">
 <div class="row mt-5">
   <div class="col-md-4">
     <div class="mb-3">
       <label for="formFile" class="form-label">Upload file example</label>
       <input (change)="this.onFilechange($event)" class="form-control" type="file" id="formFile">
       <button (click)="this.upload()" type="button" class="btn btn-primary mt-3">Upload</button>
     </div>
   </div>
 </div>
</div>

We need to pass the (change) event to our ts file so we can get the file content. Actual upload is triggered by the upload button in this example, but it’s up to your application logic.

Detect file change in angular

In Angular, it’s considered a best practice to offload network-related operations to another service. So in the app component, we merely wait for the upload button click, and forward the selected file to the upload service.

app.component.ts

import { UploadService } from './upload.service';
import { Component } from '@angular/core';
 
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent {
 
 file: File = null;
 
 constructor(
   private uploadService: UploadService
 ){
 
 }
 
 onFilechange(event: any) {
   console.log(event.target.files[0])
   this.file = event.target.files[0]
 }
 
 upload() {
   if (this.file) {
     this.uploadService.uploadfile(this.file).subscribe(resp => {
       alert("Uploaded")
     })
   } else {
     alert("Please select a file first")
   }
 }
}

Create a service for the network calls

This service actually takes care of the upload process.

upload.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
 
@Injectable({
 providedIn: 'root'
})
export class UploadService {
 
 constructor(
   private httpClient: HttpClient,
 ) { }
 
 public uploadfile(file: File) {
   let formParams = new FormData();
   formParams.append('file', file)
   return this.httpClient.post('http://localhost:3000/uploadFile', formParams)
 }
}

Here, we’re making a post request to our backend operating on http://localhost:3000 to the path of /uploadFile path.

FormData is not an angular-specific component, it represents an HTTP form submission in vanilla Js also. The Angular HttpClient accepts this as a valid argument for the body of the HTTP request.

angular file upload response

As you see, this creates a multipart request with our file in the body.

You can see how to receive and parse the file from the body of the request on a NodeJs server running expressJs in our NodeJS tutorial.

Read More →

Ready to get started?

Create an account now!