Angular 12 File Upload: Angular 12 Image Upload Example

In this Angular Image Upload demo, we will use the ng2-file-upload library to upload a file to the backend server. We use Node.js as a backend server. We install the latest version of Angular using Angular CLI and then start working on this Angular File Upload demo. If you are new to Angular, then check out the Angular Tutorial.

Angular 12 File Upload Example

To upload a file in Angular, use the ng2-file-upload library. For handling the uploaded files at the backend node.js server, we use the multer library.

Steps to upload image in Angular

Follow the below steps.

  1. Setup an Angular project.
  2. Install the rxjs-compat library.
  3. Install bootstrap library.
  4. Install the ng2-file-upload library.
  5. Create a node.js backend server and use the multer library.

Step 1: Setup an Angular Project

Now, set up the angular project using the following command.

ng new ng8fileupload

Angular 8 File Upload Tutorial

Now, spin up the angular app using the following command.

ng serve --open

Step 2: Install rxjs-compat library

So, to fill the gap between Angular and third-party packages, we need to install the rxjs-compat library. That is it.

npm install rxjs-compat --save

Now, you will not get any error regarding any rxjs observables.

Step 3: Install Bootstrap CSS Library

Go to your terminal and type the following command.

npm install bootstrap --save

Now, include the above file inside the angular.json file.

"styles": [

It will include the library in the Angular application.

Step 4: Install an ng-file-upload library.

Type the following command to install the library.

npm install ng2-file-upload --save

Now, write the following code inside an app.module.ts file.

// app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FileSelectDirective } from 'ng2-file-upload';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

  declarations: [
  imports: [
  providers: [],
  bootstrap: [AppComponent]
export class AppModule { }

We have imported the FileSelectDirective from ng2-file-upload.

Also, we need to import the FormsModule because we need to write the file upload component to upload a file to the server.

Now, write the following code inside an app.component.ts file.

// app.component.ts

import { Component, OnInit } from '@angular/core';
import {  FileUploader, FileSelectDirective } from 'ng2-file-upload/ng2-file-upload';

const URL = 'http://localhost:4000/api/upload';

  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
export class AppComponent implements OnInit {
  title = 'ng8fileupload';
  public uploader: FileUploader = new FileUploader({ url: URL, itemAlias: 'photo' });
  ngOnInit() {
    this.uploader.onAfterAddingFile = (file) => { file.withCredentials = false; };
    this.uploader.onCompleteItem = (item: any, response: any, status: any, headers: any) => {
         console.log('ImageUpload:uploaded:', item, status, response);
         alert('File uploaded successfully');

In the above code, we have imported FileUploader and FileSelectDirective from ng2-file-upload.

Also, we have defined the backend API URL, which is http://localhost:4000/api/upload.

We will create a backend server in Node.js and then send a POST request to the server.

So, here we have used the Angular Component lifecycle method called ngOnInit().

We have written the file upload code inside the ngOnInit function.

Now, the only thing remaining is written the HTML code for the file upload component.

Write the following piece code inside the app.component.html file.

<div class="container">
  <input type="file" name="photo" ng2FileSelect [uploader]="uploader" />
  <button type="button" class="btn btn-success btn-s" 
    [disabled]="!uploader.getNotUploadedItems().length" >
        Upload an Image

Now, go to the http://localhost:4200/ URL and see the output.


Install an ng-file-upload libraryNow the only thing remaining is to create a backend in Node.js.

Step 5: Create a Node.js server to handle file requests.

First, install the following node modules.

npm install express multer body-parser dotenv --save

Install nodemon as a dev dependency.

npm install nodemon --save-dev

Create a new directory inside the root of the angular project called uploads.

Okay, now create one file in the angular project root folder called server.js.

Write the following piece code inside the server.js file.

// server.js

const path = require('path');
const express = require('express');
const multer = require('multer');
const bodyParser = require('body-parser')
const app = express();

const DIR = './uploads';
let storage = multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, DIR);
    filename: (req, file, cb) => {
      cb(null, file.fieldname + '-' + + '.' + path.extname(file.originalname));
let upload = multer({storage: storage});

app.use(bodyParser.urlencoded({extended: true}));
app.use(function (req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
  res.setHeader('Access-Control-Allow-Methods', 'POST');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
  res.setHeader('Access-Control-Allow-Credentials', true);
app.get('/api', function (req, res) {
  res.end('file catcher example');
});'/api/upload',upload.single('photo'), function (req, res) {
    if (!req.file) {
        console.log("No file received");
        return res.send({
          success: false
      } else {
        console.log('file received');
        return res.send({
          success: true
const PORT = process.env.PORT || 4000;
app.listen(PORT, function () {
  console.log('Node.js server is running on port ' + PORT);

First, we have used process.env. Working with environment variables is a great way to configure different configurations of your Node.js application.

If the environment variable PORT is defined inside the .env file, it will take that variable’s value; otherwise, it will pick the value of by default, and in our case, it is 4000.

So node.js will spin up on port 4000.

We have imported the multer library. It is the node.js compatible library for handling files or image handling in the node.js.

We can store the file using the multer’s file storage function.

When the HTTP POST request of the file is coming to the node.js server, then first we have to use the body-parser module, which parses the request data and then go to the multer function and extract the file from the request and add the timestamp to the filename and save the file inside the uploads directory. So we have already defined the directory.

The final step is to start the node.js server using the following code.

nodemon server

Now, go to the frontend and try to upload a file. I have been attempting to upload an image, and it is successfully uploaded. You can see the alert() on the front end.

Create Node.js backend

This is the primary example of Image Upload in Angular. If you want to resize the image using node.js, then check out my Node.js image resize tutorial.

Also, see the uploads folder to see if the image is saved or not.

You can find more options on ng2-file-upload official documentation.

Finally, Angular File Upload Example is over. Thanks for taking it.

Recommended Posts

Angular HttpClient

Angular Observables

Angular NgFor

Angular NgStyle

Angular NgModel

Angular NgClass

10 thoughts on “Angular 12 File Upload: Angular 12 Image Upload Example”

  1. Although this will compile locally, it may not work if you compile –aot –prod for production. Instead, try importing the FileUploadModule, then placing it in imports[], not in declarations[]:

    import { FileUploadModule } from ‘ng2-file-upload’;
    /* … */
    imports: [

  2. Thanks a lot,
    here are some tips from me, when i was trying to get this working..
    1) If you cant run the server with “nodemon server”, try “npx nodemon server”
    2) If your frontend app is not on your localhost, then you can have problem with CORS policy in your browser. In chrome you can temporary disable it by running chrome by “C:\Program Files (x86)\Google\Chrome\Application\chrome.exe” –disable-web-security –user-data-dir=”c:/someFolderName”

    Happy coding to everyone, bye! 🙂

  3. Hi!
    I’m trying to use this but doesn’t work to me, I’m installed everything you said and copy & paste your code and doesn’t work. Please help me!

    My code:
    // upload.component.ts
    import { Component, OnInit } from ‘@angular/core’;

    import { FileUploader } from ‘ng2-file-upload/ng2-file-upload’;

    const URL = ‘’;

    selector: ‘app-derivados’,
    templateUrl: ‘./derivados.component.html’,
    styleUrls: [‘./derivados.component.scss’]
    export class UploadComponent implements OnInit {
    title = ‘ng8fileupload’;
    public uploader: FileUploader = new FileUploader({ url: URL, itemAlias: ‘derivados’ });
    ngOnInit() {
    this.uploader.onAfterAddingFile = (file) => { file.withCredentials = false; };
    this.uploader.onCompleteItem = (item: any, response: any, status: any, headers: any) => {
    console.log(‘ImageUpload:uploaded:’, item, status, response, headers);
    alert(‘File uploaded successfully’);

    // upload.component.html

    {{uploader | json}}

    Upload an Image

    • I’m getting this error:
      DerivadosComponent.html:12 ERROR TypeError: Converting circular structure to JSON
      –> starting at object with constructor ‘FileUploader’
      | property ‘queue’ -> object with constructor ‘Array’
      | index 0 -> object with constructor ‘FileItem’
      — property ‘uploader’ closes the circle
      at JSON.stringify ()
      at JsonPipe.push../node_modules/@angular/common/fesm5/common.js.JsonPipe.transform (common.js:5880)
      at Object.eval [as updateRenderer] (DerivadosComponent.html:12)
      at Object.debugUpdateRenderer [as updateRenderer] (core.js:30068)
      at checkAndUpdateView (core.js:29443)
      at callViewAction (core.js:29679)
      at execComponentViewsAction (core.js:29621)
      at checkAndUpdateView (core.js:29444)
      at callViewAction (core.js:29679)
      at execEmbeddedViewsAction (core.js:29642)


Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.