Web Development

Implementing File Upload Using Node and Angular

March 3rd, 2021 | By Jay Raj | 6 min read

We will explain how to implement Angular file upload using Node.js and Angular.

Using Express Node, you'll create the file upload request handler, which will upload the file to the server. You'll implement the user interface for file upload in Angular.

The source code for this tutorial is available on the GitHub repository to implement file upload using Angular and Express Node.js.

1. Creating the Angular App

Install the Angular CLI on your system and use the Angular CLI using Node Package Manager (npm).

npm install -g @angular/cli


Now, 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.

2. Creating the Angular File Upload UI

The default Angular boilerplate code creates an Angular component called AppComponent in the src/app/ folder. It has an HTML file, a controller file, and a CSS file.

Remove the HTML code from 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 to style up the Angular file upload user interface. 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 to see the Angular file upload user interface.

implementing-file-upload-node-angular-file-upload-ui

3. Creating the Node.js File Upload Handler

You will need a file upload handler to handle the request sent from the Angular application. Use 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


After initializing the Node project, install the Express framework using npm.

npm install --save express


Create a file called app.js inside the project folder. You will use the 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}!`))


You've created the Express app using the Express module. Then, you have 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 that handles POST requests. Modify the existing one to be a POST route.

You'll be using the connect-multiparty module to handle file uploads, 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-multiparty middleware to the POST file upload route.

app.post('/api/upload', multipartMiddleware, (req, res) => {
    res.json({
        'message': 'File uploaded successfully'
    });
});


Use the body-parser module to parse the file upload request posted to the file handler route. 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.

4. Angular File Upload to server

Route the Angular file upload requests to the Node server by setting a proxy inside the 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


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 uploaded files array gets updated with uploaded files, which can be posted to the file upload route with a 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, browse for a file, and click the upload button. 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 Angular file upload using both Angular and Node.js.

You used the Express framework for writing the file upload handler.

You are more confident to experiment with file upload Angular components in your projects.

Also, if you're building Angular applications with sensitive logic, be sure to protect them against code theft and reverse engineering by following our guide about how to protect Angular code.

Jscrambler

The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.

View All Articles

Must read next

Web Development

10 Tips For Optimizing Node.js Applications

10 useful optimization tips to take the most of your Node.js server application. From asynchronous functions to enabling streaming responses.

July 5, 2016 | By Jscrambler | 4 min read

Web Development

Getting Started with Angular 2

Angular 2 has been built to be completely decoupled from the DOM, meaning that developers can use the framework to build more than just web applications.

November 10, 2016 | By Thomas Greco | 6 min read

Section Divider