In this tutorial, you'll learn how to implement file upload using Angular and Node.js. Using Express Node, you'll create the file upload request handler which will upload the file to the server. You'll implement the file upload user interface using Angular.
The source code from this tutorial is available on GitHub.
Creating the Angular App
To get started with this tutorial, you'll need to install the Angular CLI in your system. Let's get started with installing the Angular CLI using Node Package Manager (npm).
npm install -g @angular/cli
Once you have installed the Angular CLI, create an Angular app using the command line tool.
ng new angular-file-upload
The above command will create the Angular project boilerplate. Navigate to the project directory and start the Angular app.
cd angular-file-upload
npm start
Point your browser to http://localhost:4200
and you will have the default application running.
Creating the File Upload UI
The default Angular boilerplate code creates an Angular component called AppComponent
in the src/app/
folder. A component has an HTML file, a controller file, and a CSS file.
Remove the HTML code from the src/app/app.component.html
and add the following code:
<div class="mainContainer">
<div class="content">
<div class="header">
<h1>Angular File Upload</h1>
</div>
<div class="row margin25">
<div class="col-md-4">
</div>
<div class="col-md-4">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text upload" id="btnUpload">Upload</span>
</div>
<div class="custom-file">
<form action="/api/upload" method="post" enctype="multipart/form-data">
<input type="file" class="custom-file-input" id="inputGroupFile01" aria-describedby="inputGroupFileAddon01">
</form>
<label class="custom-file-label" for="inputGroupFile01">Choose file</label>
</div>
</div>
</div>
<div class="col-md-4">
</div>
</div>
</div>
</div>
Add the following CSS style to the src/app/app.component.css
file.
.header {
text-align: center;
}
.header h1 {
font-family: serif;
font-size: 38px;
font-family: 'Times New Roman';
}
.content {
margin: 100px;
}
.margin25 {
margin: 25px;
}
.upload {
cursor: pointer;
}
You'll be using bootstrap
for styling up the Angular user interface. So, install bootstrap
using npm inside the Angular project.
npm install --save bootstrap
Once you have installed bootstrap
, include the Bootstrap style inside the angular.json
file under the build configurations.
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
]
Save the application and you will be able to see the Angular user interface for file upload.
Creating the Node.js File Upload Handler
You need a file upload handler to handle the request sent from the Angular application. You'll be making use of the Express framework for creating the Node handler.
Create a folder called file-upload-server
and initialize the Node project inside it.
mkdir file-upload-folder
cd file-upload-folder
npm init
Once you have the Node project initialized, install the express
framework using npm.
npm install --save express
Create a file called app.js
inside the project folder. You'll be making use of body-parser
to parse the post parameter to the request handler. Install it now:
npm install --save body-parser
You'll also be using the connect-multiparty
module to upload the file.
npm install --save connect-multiparty
Once you have the required dependencies for writing the file upload handler, let's start by creating the Express app. Add the following code to the app.js
file:
const express = require('express')
const app = express()
const port = 3000
app.get('/api/upload', (req, res) => {
res.json({
'message': 'hello'
});
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
As seen in the above code, you created the Express app using the express
module. After creating the app, you defined the Express route /api/upload
which returns a JSON message.
Save the above changes and start the Express app.
node app.js
Point your browser to http://localhost:3000/api/upload
and you will have the JSON response rendered in the browser.
For writing the file upload request handler, you'll need a route which handles POST requests. So, modify the existing route to a POST route.
You'll be using the connect-multiparty
module to handle file upload, so require the module and define the file upload folder. Make sure to create a folder called uploads
inside the project directory.
const multipart = require('connect-multiparty');
const multipartMiddleware = multipart({ uploadDir: './uploads' });
Add the connect-mutiparty
middleware to the POST file upload route.
app.post('/api/upload', multipartMiddleware, (req, res) => {
res.json({
'message': 'File uploaded successfully'
});
});
In order to parse the file upload request posted to the file handler route, you need to make use of the body-parser
module. So, require the body-parser
module and use it across the application.
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
Here is how the app.js file looks:
const express = require('express')
const app = express()
const port = 3000
const bodyParser = require("body-parser");
const multipart = require('connect-multiparty');
const multipartMiddleware = multipart({
uploadDir: './uploads'
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.post('/api/upload', multipartMiddleware, (req, res) => {
res.json({
'message': 'File uploaded succesfully.'
});
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
Save the changes and run the Node app.
node app.js
You will have the Express app running at http://localhost:3000
.
File Upload From Angular
To route the file upload requests from Angular to the Node server, you need to set a proxy inside the Angular app. In the Angular app directory, create a proxy.conf.json
file and add the following code to set a proxy to the node server.
{
"/api/*": {
"target": "http://localhost:3000/", "secure": false
}
}
From the package.json
file, modify the start
script to serve the Angular app using the proxy.
ng serve --proxy-config proxy.conf.json
Now, add a file change event to the input type file element inside the app.component.html
file.
<input (change)="fileChange($event)" type="file" class="custom-file-input" id="inputGroupFile01" aria-describedby="inputGroupFileAddon01">
Define the fileChange
method inside the app.component.ts
file.
fileChange(element) {
this.uploadedFiles = element.target.files;
}
On file change, the uploadedFiles
array gets updated with uploaded files which can be posted to the file upload route on button click. Add the upload
click event to the Upload button.
<span class="input-group-text upload" (click)="upload()" id="btnUpload">Upload</span>
Define the upload
method inside the app.component.ts
file.
upload() {
let formData = new FormData();
for (var i = 0; i < this.uploadedFiles.length; i++) {
formData.append("uploads[]", this.uploadedFiles[i], this.uploadedFiles[i].name);
}
this.http.post('/api/upload', formData)
.subscribe((response) => {
console.log('response received is ', response);
})
}
Iterating the uploadedFiles
array, you create the formData
and POST it to the Express file handler /api/upload
.
Here is how the app.component.ts
file looks:
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
uploadedFiles: Array < File > ;
constructor(private http: HttpClient) {
}
ngOnInit() {
}
fileChange(element) {
this.uploadedFiles = element.target.files;
}
upload() {
let formData = new FormData();
for (var i = 0; i < this.uploadedFiles.length; i++) {
formData.append("uploads[]", this.uploadedFiles[i], this.uploadedFiles[i].name);
}
this.http.post('/api/upload', formData)
.subscribe((response) => {
console.log('response received is ', response);
})
}
}
Save the above changes and browse a file and click the upload button. On successful file upload, a success message will be logged in the browser console.
You can find the uploaded file in the uploads
folder inside the Node server app.
Conclusion
In this tutorial, you learned how to implement file upload using Angular and Node.js. You used the Express framework for writing the file upload handler.
Also, if you're building Angular applications with sensitive logic, be sure to protect them against code theft and reverse-engineering by following this guide.
Originally posted on the Jscrambler Blog by Jay Raj.