How to Integrate Angular 10 with Node.js Restful Services

In this tutorial, I will show you step by step to integrate Angular 10 project with Node.js Restful Services so that we only need to run both on same Server/Port. You will also know how to configure Angular SPA Routing to avoid 404 on refresh.

Related Posts:
Angular 10 + Node.js Express + MySQL example
Angular 10 + Node.js Express + MongoDB example
Angular 10 + Node.js Express + PostgreSQL example
Angular 10 + Node.js Express: JWT Authentication & Authorization example
Angular 10 File upload example with progress bar
Server side Pagination with Node.js and Angular


Angular 10 & Node.js Express Application Overview

Assume that we have 2 separated projects: Angular 10 & Node.js Express like this-

integrate-angular-10-node-js-restful-services-project-structure

For example, if we run them separately:

  • Node.js Server exports Restful Services at Url: http://localhost:8080/
  • Angular 10 Client runs at url: http://localhost:8081/

Using Angular 10 to call Node.js Rest API:

integrate-angular-10-node-js-restful-services-run-separated-port

Otherwise, when deploying Angular 10 production-build with Node.js Express project, we only need to run Node Project for the fullstack (Angular 10 + Node) system.

In this example, we access http://localhost:8080/.

integrate-angular-10-node-js-restful-services-same-server-hash-routing

Technology Stack

  • Node.js
  • Express
  • Angular 10

Setup Angular Client

You can use your own Angular Project, or just download the source code on Github, or follow these steps to create a new one.

Open cmd and use Angular CLI to create a new Angular Project as following command:

ng new Angular10Client
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? CSS

We also need to generate some Components and Services:

ng g s services/tutorial

ng g c components/add-tutorial
ng g c components/tutorial-details
ng g c components/tutorials-list

Now you can see that our project directory structure looks like this-

integrate-angular-10-node-js-restful-services-project-structure-angular

Because I want to keep this tutorial simple and brief, please continue to develop this App with instruction in the post:
Angular 10 CRUD Application example with Web API

Setup Node.js Express Server

You can use your own Node.js Project, or just download the source code on Github, or follow these steps to create a new one.

First, we create a folder:

$ mkdir angular-10-node-js-example
$ cd angular-10-node-js-example

Next, we initialize the Node.js App with a package.json file:

npm init

name: (angular-10-node-js-example) 
version: (1.0.0) 
description: Integrate Angular 10 with Node.js Restful Services example
entry point: (index.js) server.js
test command: 
git repository: 
keywords: angular, angular 10, nodejs, express, sequelize, rest api, restful services
author: bezkoder
license: (ISC)

Is this ok? (yes) yes

The instruction can be found in one of the posts:
Node.js Rest APIs example with Express, Sequelize & MySQL
Node.js Rest APIs example with Express, Sequelize & PostgreSQL
Node.js Rest APIs example with Express, Sequelize & MongoDb

Let’s continue to the most important part.

Integrate Angular 10 with Node.js Restful Services

Build Angular 10 App Production

Currently Angular Client and Spring Boot server work independently on ports 8081 and 8080.

The first thing we need to do is to build Angular App for production.
There are 2 steps:
– Set the output directory to static folder:
Open angular.json, add the "outputPath": "./static" option to the build target so that the production will be stored in static folder under project root directory.

{
  ...
  "projects": {
    "Angular10Client": {
      ...
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "./static",
            "index": "src/index.html",
            "main": "src/main.ts",
            ...
          },
          "configurations": {
            ...
          }
        },
        ...
      }
    }},
  "defaultProject": "Angular10Client"
}

– Run command ng build --prod.

chunk {} runtime.e227d1a0e31cbccbf8ec.js (runtime) 1.45 kB [entry] [rendered]
chunk {1} main.caa4408d70df33b5b874.js (main) 267 kB [initial] [rendered]
chunk {2} polyfills.a4021de53358bb0fec14.js (polyfills) 36.1 kB [initial] [rendered]
chunk {3} styles.3ff695c00d717f2d2a11.css (styles) 0 bytes [initial] [rendered]
Date: 2020-11-09T02:21:10.973Z - Hash: 3da9b9b26aa6744982e5 - Time: 38044ms

Now you can see new static folder with content as following:

integrate-angular-10-node-js-restful-services-build-folder

Integrate Angular 10 production with Node.js Project

In app folder of Node.js Express Project, let’s create views folder.


app

config

controllers

models

routes

views

index.js

package.json

server.js


Now we need to copy all files from Angular static folder to app/views folder above.

The final Node.js Project folder structure will be like this:

integrate-angular-10-node-js-restful-services-final-project

Serve Angular 10 App with Express

We’re gonna serve static files such as HTML files, CSS files and JavaScript files in app/views folder using the express.static() built-in middleware function.

const express = require("express");

const path = __dirname + '/app/views/';
const app = express();

app.use(express.static(path));

The final step is to deliver index.html file using res.sendFile(). We will need to pass in a path to the file.

// const path = __dirname + '/app/views/';

app.get('/', function (req,res) {
  res.sendFile(path + "index.html");
});

Now content in server.js file is like this-

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");

const path = __dirname + '/app/views/';

const app = express();

app.use(express.static(path));

var corsOptions = {
  origin: "http://localhost:8081"
};

app.use(cors(corsOptions));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

const db = require("./app/models");

db.sequelize.sync();

app.get('/', function (req,res) {
  res.sendFile(path + "index.html");
});

require("./app/routes/turorial.routes")(app);

// set port, listen for requests
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}.`);
});

Run Node Express server & Angular 10 on the same Port

Run the Node.js Express server (including Angular 10 client) with commands:
node server.js

Open browser with url: http://localhost:8080/.
Now you can see the result:

integrate-angular-10-node-js-restful-services-run-same-server-port

Express & Angular 10: Refresh page error 404

Oh yeah! Everything looks good.
But wait, let’s try to refresh the page.
What happened?

integrate-angular-10-node-js-restful-services-404-on-refresh

To handle this error, we’re gonna enable hash(#) in App Routing module.

– Open app-routing.module.ts
– Pass optional parameter useHash as true value.

@NgModule({
  imports: [RouterModule.forRoot(routes, {useHash: true})],
  exports: [RouterModule]
})

Our Url is hashed(#) after port number: http://localhost:8080/#/tutorials

integrate-angular-10-node-js-restful-services-same-server-hash-routing

Now you can refresh the page without worrying about 404.

Conclusion

Today we’ve learned how to integrate Angular 10 with Node.js Restful Services on same Server/Port. We also handle the case Refresh page error by adding hash(#) to the urls.

There are many Angular 10 + Node.js examples that you can apply this approach to integrate:
Angular 10 + Node.js Express + MySQL example
Angular 10 + Node.js Express + MongoDB example
Angular 10 + Node.js Express + PostgreSQL example
Angular 10 + Node.js Express: JWT Authentication & Authorization example
Angular 10 File upload example with progress bar
Server side Pagination with Node.js and Angular

Or Serverless with Firebase:
Angular 10 Firebase CRUD Realtime Database
Angular 10 Firestore CRUD with AngularFireStore

Further Reading

Source Code

You can find the complete source code for this tutorial at Github.

Leave a Reply

Your email address will not be published. Required fields are marked *