Welcome folks today in this blog post we will be uploading single or multiple
files in node.js and express
using multer
library in typescript. All the full source code of the application is shown below.
Get Started
In order to get started you need to make a new directory
and inside it we will be making the frontend
and backend
app as shown below
mkdir uploadapp
cd uploadapp
Now we need to make directory for frontend
app angular
mkdir frontend
cd frontend
After that we will making a new angular app
as shown below
ng new sampleapp
Now you will see the below directory
structure of the angular app as shown below
And now we need to include the HtppClientModule
and FormsModule
in the app.module.ts
file as shown below
app.module.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from '@angular/common/http'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule, FormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } |
Now we need to go to app.component.html
file and copy paste the below html template
as shown below
app.component.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<h1 style="text-align: center;">Angular 13 File Upload in Node.js and Express</h1> <div style="text-align: center;"> <form> <div> <input #singleInput type="file" name="image" (change)="selectImage($event)"> </div> <br> <div> <button type="submit" (click)="onSubmit()">Upload</button> </div> <ng-template [ngIf]="displaySingleImage" [ngIfElse]="elseSingleImageTemplate"> <div>Images Uploaded</div> <ul> <li *ngFor='let image of displaySingleImageArray'> <img src="http://localhost:3000/{{image}}"/> </li> </ul> </ng-template> <ng-template #elseSingleImageTemplate> <br /><br /> <div>Please Upload Some Images</div> </ng-template> </form> </div> <hr /> <h2 style="text-align: center">Multiple</h2> <div style="text-align: center"> <form> <div> <input #multipleInput type="file" name="images" multiple (change)="selectMultipleImage($event)" /> </div> <br /> <div> <button type="submit" (click)="onMultipleSubmit()"> Multiple Upload </button> </div> </form> <ng-template [ngIf]="displayMultipleImages" [ngIfElse]="elseMultipleImagesTemplate" > <div>Images Uploaded</div> <ul> <li *ngFor='let image of displayMultipleImageArray'> <img src="http://localhost:3000/{{image}}"/> </li> </ul> </ng-template> <ng-template #elseMultipleImagesTemplate> <br /><br /> <div>Please Upload Some Images</div> </ng-template> </div> |
As you can see we have two sections
in which we can upload single or multiple
files
Now we need to go to app.component.ts
file and copy paste the typescript
code to make the http
post request at the backend
express api to upload files
app.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
import { Component, ElementRef, ViewChild } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { title = 'uploadfile'; displaySingleImage!: Boolean; displayMultipleImages!: Boolean; displayMultipleImageArray!: Array<any>; displaySingleImageArray!: Array<any>; @ViewChild('singleInput', { static: false }) singleInput!: ElementRef; @ViewChild('multipleInput', { static: false }) multipleInput!: ElementRef; images: any; multipleImages = []; constructor(private http: HttpClient) { this.displaySingleImage = false; this.displayMultipleImageArray = []; this.displayMultipleImages = false; this.displaySingleImageArray = []; } selectImage(event: any) { if (event.target.files.length > 0) { const file = event.target.files[0]; console.log(file); this.images = file; } } onSubmit() { // construct formdata const formdata = new FormData(); formdata.append('file', this.images); // post request to express backend this.http.post<any>('http://localhost:3000/file', formdata).subscribe( (res) => { console.log(res); this.singleInput.nativeElement.value = ''; this.displaySingleImage = true; this.displaySingleImageArray.push(res.path); }, (err) => { console.log(err); } ); } selectMultipleImage(event: any) { if (event.target.files.length > 0) { this.multipleImages = event.target.files; } } onMultipleSubmit() { const formdata = new FormData() for (let img of this.multipleImages) { formdata.append('files',img) } this.http.post<any>('http://localhost:3000/multipleFiles', formdata) .subscribe((res) => { console.log(res) this.multipleInput.nativeElement.value = "" console.log(res.path) this.displayMultipleImages=true this.displayMultipleImageArray = res.path }) } } |
And now we need to make the backend
folder and inside it we need to make a new express
server as shown below
mkdir backend
cd backend
npm init -y
npm i express cors multer
And after that you will see the below directory
structure of the express app as shown below
And also we need to make the uploads
directory where you need to store the uploaded
images inside the web app.
Now you need to go to index.js
file and copy paste the following code
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
const express = require('express') const multer = require('multer') const cors = require('cors') const bodyparser = require('body-parser') const path = require('path') const app = express() app.use(express.static(path.join(__dirname + "/uploads"))) app.use(bodyparser.urlencoded({ extended: false })) app.use(bodyparser.json()) app.use(cors()) var storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, "uploads"); }, filename: function (req, file, cb) { cb(null, Date.now() + path.extname(file.originalname)); //Appending extension }, }); var upload = multer({ storage: storage }).single('file'); var multipleUpload = multer({storage:storage}).array('files') app.post('/file', (req, res) => { upload(req, res, (err) => { if (err) { console.log(err) } console.log(req.file.path) res.json({ path:req.file.filename }) }) }) app.post('/multiplefiles', (req, res) => { multipleUpload(req, res, (err) => { if (err) { console.log(err) } console.log(req.files) let img = [] req.files.forEach(file => { img.push(file.filename) }); res.json({ path:img }) }) }) app.listen(3000, () => { console.log("App is listening on port 3000") }) |
As you can see we are receiving the files
selected inside the angular app and then we are uploading the files to uploads
folder using the multer
library. And then we are sending the paths
of the uploaded files as json to the angular
frontend and then displaying it.
You can start the express
app by executing the below command as shown below
nodemon index.js
It will start the express app at port 3000
and now we can start the angular app
by executing the below command as shown below
ng serve
Now If I try to upload files using the frontend
it will look something like this as shown below