Home >>Angular8 Tutorial >Angular8 project

Angular8 project

Create an Angular8 project

Let's create an Angular 8 project by using the following command:

ng new angular8project

Install Bootstrap 4 CSS framework

To load bootstrap into your project, use the following command.

npm install bootstrap --save

Now, add the following code inside the angular.json file.

"styles": [  
   "src/style.css",  
   "./node_modules/bootstrap/dist/css/bootstrap.min.css"  
 ],  

Start the Angular development server using the following command.

ng serve -o

Project Description

  • To enter and apply your ProductName, Product Definition, and ProductPrice to a document.
  • Validate the meaning over type. If values are incorrect, the front end will be validated and the form will not be submitted.
  • Send the form to the Node.js Backend API, if all values are correct.
  • Store values within database of MongoDB.
  • Display frontend data.
  • Often allows uploading and deletion of data by users.
  • Show up the MongoD CLI data.
  • Display the MongoDB Compass Community data (a MongoDB database GUI).

Generate Angular Components

We will do a CRUD operation for creating, reading, and updating data. So, we 're going to create 3 components.

To create 3 Angular Components using the following command:

ng g c product-add --skipTests=true  
ng g c product-get --skipTests=true  
ng g c product-edit --skipTests=true 

Inside the src > > app folder in your project file you can check the app-routing.module.ts file. It's generated because we require angular cli to produce the routing file for us when we install an angular app.

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


// app-routing.module.ts  
import { NgModule } from '@angular/core';  
import { Routes, RouterModule } from '@angular/router';  
import { ProductAddComponent } from './product-add/product-add.component';  
import { ProductEditComponent } from './product-edit/product-edit.component';  
import { ProductGetComponent } from './product-get/product-get.component';  
const routes: Routes = [  
  {  
    path: 'product/create',  
    component: ProductAddComponent  
  },  
  {  
    path: 'edit/:id',  
    component: ProductEditComponent  
  },  
  {  
    path: 'products',  
    component: ProductGetComponent  
  }  
];  
@NgModule({  
  imports: [RouterModule.forRoot(routes)],  
  exports: [RouterModule]  
})  
export class AppRoutingModule { }  

Now you can see that directive is inside the app.component.html file. This directive helps us to render the various component based on the URI of route.

Create Angular Navigation

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


<nav class="navbar navbar-expand-sm bg-light">  
  <div class="container-fluid">  
    <ul class="navbar-nav">  
      <li class="nav-item">  
        <a routerLink="product/create" class="nav-link" routerLinkActive="active">  
          Product  
        </a>  
      </li>  
      <li class="nav-item">  
        <a routerLink="products" class="nav-link" routerLinkActive="active">  
          Link   
        </a>  
      </li>   
    </ul>  
  </div>  
</nav>  
<div class="container">  
  <router-outlet></router-outlet>  
</div>  

Install Angular Routing Progress Indicator

Type the following command to install the ng2-slim-loading-bar library.

npm install ng2-slim-loading-bar --save  

If you have third party packages installed right now, then Angular 8 is not compatible. You will need to install the following library to solve the problem between Angular 8 and third-party packages.

npm install rxjs-compat --save  

Now, import the SlimLoadingBarModule inside an app.module.ts file.


import { SlimLoadingBarModule } from 'ng2-slim-loading-bar';  
imports: [  
    ...  
    SlimLoadingBarModule  
],  
Now, include the styling that comes with the library inside src >> styles.css file.

@import "../node_modules/ng2-slim-loading-bar/style.css";  
	

Adding Router Events

  • NavigationStart
  • NavigationEnd
  • NavigationError
  • NavigationCancel
  • Router
  • Event

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


import { Component } from '@angular/core';  
import {SlimLoadingBarService} from 'ng2-slim-loading-bar';  
import { NavigationCancel,  
 Event,  
        NavigationEnd,  
        NavigationError,  
        NavigationStart,  
        Router } from '@angular/router';  
@Component({  
  selector: 'app-root',  
  templateUrl: './app.component.html',  
  styleUrls: ['./app.component.css']  
})  
export class AppComponent {  
  title = 'Angular 8';  
  constructor(private loadingBar: SlimLoadingBarService, private router: Router) {  
    this.router.events.subscribe((event: Event) => {  
      this.navigationInterceptor(event);  
    });  
  }  
  private navigationInterceptor(event: Event): void {  
    if (event instanceof NavigationStart) {  
      this.loadingBar.start();  
    }  
    if (event instanceof NavigationEnd) {  
      this.loadingBar.complete();  
    }  
    if (event instanceof NavigationCancel) {  
      this.loadingBar.stop();  
    }  
    if (event instanceof NavigationError) {  
      this.loadingBar.stop();  
    }  
  }  
}  

In the code above, in Angular application we have specified that if the user navigates from one component to another component, the progress result will be shown.

When the user clicks the other route, the angular progress indicator starts displaying and when the navigation is complete, the display will simply stop. So, for the user this is kind of UX.

The above code intercepts the routing event and applies the loading bar element to each path, so that every time we change routes we can see the routing sign.

Inside the app.component.html file at the top of the page we must add the ng2-slim-loading-bar directive.

<!-- app.component.html -->  
<ng2-slim-loading-bar color="red"></ng2-slim-loading-bar>  
<nav class="navbar navbar-expand-sm bg-dark">  
<div class="container-fluid">  
<ul class="navbar-nav">  
<li class="nav-item">  
<a routerLink="product/create" class="nav-link" routerLinkActive="active">  
Product  
</a>  
</li>  
<li class="nav-item">  
<a routerLink="products" class="nav-link" routerLinkActive="active">  
Link  
</a>  
</li>   
</ul>  
</div>  
</nav>  
<div class="container">  
<router-outlet></router-outlet>  
</div>  

Add Bootstrap Form

Add the following bootstrap 4 form Inside the product-add.component.html file.


<div class="card">  
  <div class="card-body">  
    <form>  
      <div class="form-group">  
        <label class="col-md-4">TOPIC</label>  
        <input type="text" class="form-control" />  
      </div>  
      <div class="form-group">  
        <label class="col-md-4">ONE </label>  
        <textarea class="form-control" rows = 7 cols = "5"></textarea>  
      </div>  
      <div class="form-group">  
        <label class="col-md-4">TWO</label>  
        <input type="text" class="form-control" />  
      </div>  
      <div class="form-group">  
        <button type="submit" class="btn btn-primary">Click me</button>  
      </div>  
    </form>  
  </div>  
</div>  

Add Angular 8 Form Validation


	import { ReactiveFormsModule } from '@angular/forms';  
imports: [  
    ...  
    ReactiveFormsModule  
],  

You need to remember that this is not a template-driven type here, and you need to modify the app.component.ts file.

Here, we have to import from @angular / forms the FormGroup, FormBuilder, Validators modules, and build a constructor and instance the FormBuilder.

So, within the product-add.component.ts file, write the following code.


import { Component, OnInit } from '@angular/core';  
import { FormGroup,  FormBuilder,  Validators } from '@angular/forms';  
@Component({  
  selector: 'app-product-add',  
  templateUrl: './product-add.component.html',  
  styleUrls: ['./product-add.component.css']  
})  
export class ProductAddComponent implements OnInit {  
  angForm: FormGroup;  
  constructor(private fb: FormBuilder) {  
    this.createForm();  
  }  
  createForm() {  
    this.angForm = this.fb.group({  
      PN: ['', Validators.required ],  
      PD: ['', Validators.required ],  
      PP: ['', Validators.required ]  
    });  
  }  
  ngOnInit() {  
  }  
}  

Here we use form builder to manage the whole validation process. Now, we have to create a form with the validation rules in that constructor. There are three fields, in our example. If the text input is empty, otherwise an error may arise and we need to show the error.

Now write the code below within the file product-add.component.html.

Configure the HttpClientModule

To connect with the backend services, Front-end applications often need HTTP protocol. Modern browsers support two separate HTTP request-making APIs: the javaHttpRequest interface, and the fetch (API).

Import in an app.module.ts package the HttpClientModule.


// app.module.ts  
import { HttpClientModule } from '@angular/common/http';  
imports: [  
   ...  
    HttpClientModule  
 ],  

Create a model file

Inside the src >> app folder, create one file called Product.ts and add the following code.

	
export default class Product
{  
  PN: string;  
  PD: string;  
  PP: number;  
}  

Create an Angular Service file

Type the following command to generate the service file.

ng g service products --skipTests=true  

After creation, it will look like this:


import { Injectable } from '@angular/core';  
@Injectable({  
  providedIn: 'root'  
})  
export class ProductsService {  
  
  constructor() { }  
}  

Now, import the products.service.ts file into the app.module.ts file.


import { ProductsService } from './products.service';  
providers: [ ProductsService ],  

Submit the data to the node server

Now we have to write the code that will send the request for HTTP POST with the data to the server Node.js and then save the data to the database MongoDB.


Write the code below within the product.service.ts file.
import { Injectable } from '@angular/core';  
import { HttpClient } from '@angular/common/http';  
@Injectable({  
  providedIn: 'root'  
})  
export class ProductsService {  
  uri = 'http://localhost:4000/products';  
  constructor(private http: HttpClient) { }  
  addProduct(PN, PD, PP) {  
    const obj = {  
      PN,  
      PD,  
      PP  
    };  
    console.log(obj);  
    this.http.post(`${this.uri}/add`, obj)  
        .subscribe(res => console.log('Done'));  
  }  
}  

Now, we need to attach the click event to the Product Add button. Thus, within the product-add.component.html file add the following files.


<div class="form-group">  
        <button (click) = "addProduct(PN.value, PD.value, PP.value)" type="submit" class="btn btn-primary"  
        [disabled]="angForm.pristine || angForm.invalid" >  
          Product  
        </button>  
</div>  

Now within the product-add.component.ts package, apply the feature addProduct). So, within the product-add.component.ts file, write the following code.

	
		import { Component, OnInit } from '@angular/core';  
import { FormGroup, FormBuilder, Validators } from '@angular/forms';  
import { ProductsService } from '../products.service';  
@Component({  
  selector: 'app-product-add',  
  templateUrl: './product-add.component.html',  
  styleUrls: ['./product-add.component.css']  
})  
export class ProductAddComponent implements OnInit {  
  
  angForm: FormGroup;  
  constructor(private fb: FormBuilder, private ps: ProductsService) {  
    this.createForm();  
  }  
  createForm() {  
    this.angForm = this.fb.group({  
      PN: ['', Validators.required ],  
      PD: ['', Validators.required ],  
      PP: ['', Validators.required ]  
    });  
  }  
  addProduct(PN, PD, PP) {  
    this.ps.addProduct(PN, PD, PP);  
  }  
  ngOnInit() {  
  }  
}  
	

Create a Node.js backend API

Create a folder in an angular root folder called the api, and go inside that folder. It would be the entire project, apart from the Angular version. Therefore the directories node modules are separate from those of the Angular project.

Open the terminal in the api folder, and type the command below. Using NPM it will create the package.json file.

Install the following node specific modules.

	npm install express body-parser cors mongoose –save

Install the nodemon server and it should make it easy for you not to launch node service if you adjust it. It immediately restarts node.js server.

npm install nodemon --save-dev  

const express = require('express'),  
    path = require('path'),  
    bodyParser = require('body-parser'),  
    cors = require('cors'),  
    mongoose = require('mongoose');  
    const app = express();  
    let port = process.env.PORT || 4000;  
    const server = app.listen(function(){  
        console.log('Listening on port ' + port);  
    });  

Now, connect our node express application to the MongoDB database.

If you have not installed a MongoDB database then install it and then use the following command to start the Mongodb server.

mongod

Now, we have connected to the database.

Create one file called DB.js inside the api root project folder. Write the following code inside a DB.js file.

module.exports = {  
  DB: 'mongodb://localhost:27017/ng8crud'  
};  

Import this DB.js file into our server.js file, and use the mongoose module to set up the MongoDB database connection. To connect our MongoDB application to the Node.js api, write the following code within the server.js server.


const express = require('express'),  
    path = require('path'),  
    bodyParser = require('body-parser'),  
    cors = require('cors'),  
    mongoose = require('mongoose'),  
    config = require('./DB');  
    mongoose.Promise = global.Promise;  
    mongoose.connect(config.DB, { useNewUrlParser: true }).then(  
      () => {console.log('Connected') },  
      err => { console.log('Not connect'+ err)}  
    );  
    const app = express();  
    app.use(bodyParser.json());  
    app.use(cors());  
    const port = process.env.PORT || 4000;  
    const server = app.listen(port, function(){  
     console.log('Listening on port ' + port);  
    });  

Save this server.js file and go to the terminal and start the node server using the following command.

npm start

So, right now, there are three servers running:

Node.js Server

Angular Development Server

MongoDB server

Create model and routes for your application

We now need to build two directories inside the api root folder called routes and models.

Let's build a model in models folder named Product.js with the following code.


const mongoose = require('mongoose');  
const Schema = mongoose.Schema;  
// Define collection and schema for Product  
let Product = new Schema({  
  ProductName: {  
    type: String  
  },  
  ProductDescription: {  
    type: String  
  },  
  ProductPrice: {  
    type: Number  
  }  
},{  
    collection: 'Product'  
});  
module.exports = mongoose.model('Product', Product);  

We have established our Product Selection scheme here. We have three fields called ProductName, DescriptionProduct, ProductPrice.

Create one file named product.route.js in the routes folder.

Inside the product.route.js file write the following CRUD code.