-
Book Overview & Buying
-
Table Of Contents
MongoDB, Express, Angular, and Node.js Fundamentals
By :
Create a new Angular project named blog by pointing your CLI to the Blogging Application directory, and create an Angular CLI application with the name blog using the following code:
ng new blog
Import the bootstrap theme and its resources from http://bit.ly/2DI7UsR by opening the link, and download the bootstrap theme and resources into the blog/src/assets folder.
Update index.html with the necessary resource links using the following code:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Blog</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> //[…] <script type="text/javascript" src="assets/js/main.js"></script> </body> </html>
File name: index.html
Live link: http://bit.ly/2HDFQuT
File name: header.component.html
Live link: http://bit.ly/2Rt5h1Q
File name: blog-home.component.html
Live link: http://bit.ly/2FXWZh9
File name: footer.component.html
Live link: http://bit.ly/2UnBZ6s
File Name: view-post.component.html
Live link: http://bit.ly/2FWIJoP
Create the header components and update the HTML template with the theme's header using the following code:
ng generate component header
<nav class="navbar navbar-expand-lg navbar-dark absolute_header">
<div class="container">
<a class="navbar-brand" href="#">
<img class="etcodes-normal-logo" src="assets/images/logo-light.png" width="84" height="22" alt="Logo">
<img class="etcodes-mobile-logo" src="assets/images/logo.png" width="84" height="22" alt="Logo">
</a>
<button class="navbar-toggler hamburger-menu-btn" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown"
//[…]
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>Create the title-header component using the following code:
<div class="bg-img-71 py-100px py-md-200px mb-80px">
<div class="container">
<div class="row">
<div class="col-lg-6 offset-lg-3 text-center all-text-content-white">
<h1>MEAN Stack Courseware Blog Application Project</h1>
<p>Aenean lacinia bibendum sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce
dapibus pertinax vix, varius cursus turpis dign issim id aliquam habemus tractatos.</p>
</div>
</div>
</div>
</div>Create the blog-home components and update the HTML template with the theme's content:
ng generate component blog-home
<!-- Blogs -->
<title-header></title-header>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="row blog_posts stander_blog">
<div class="col-md-6 col-lg-4">
<article>
<div class="post_img card-blog-img">
<img src="assets/images/home-27/2.jpg" alt="Card image cap">
<a href="blog-standard-two-col-right-sidebar.html">
<span class="card-blog-meta">
//[…]
</div>
</div>
</div>
</div>Create the footer components and update the HTML template with the theme's footer:
ng generate component footer
<footer class="web-footer footer bg-color-blackflame all-text-content-white">
<div class="footer-widgets pt-85px pb-55px">
<div class="container">
<div class="row large-gutters">
<div class="col-lg-5 mb-30px">
<div class="footer-widget">
<h3>Paulappz</h3>
<p class="pt-20px pt-lg-155px">© 2018 Paulappz Themes</p>
//[…]
</div>
</div>
</div>
</div>
</footer>Create the view-post components and update the HTML template:
ng generate component view-post
<div class="page-container scene-main scene-main--fade_In">
<!-- view post -->
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="post_img">
<img src="assets/images/b3.jpg" alt="Card image cap">
//[…]
</div>
</div>
</div>
</div>
</div>Update the root component template with the following code:
<div id="main-content" class="bg-color-gray">
<app-header></app-header>
<div class="page-container scene-main scene-main--fade_In">
<app-blog-home></app-blog-home>
<app-footer></app-footer>
</div>
</div>Run ng serve -o to start the application. You will obtain the following output in the browser:

Figure 3.16: Blog application theme update
Figure 3.17: Blog application theme update
Update the root component template with the following code:
<div id="main-content" class="bg-color-gray">
<app-header></app-header>
<div class="page-container scene-main scene-main--fade_In">
<view-post></view-post>
<app-footer></app-footer>
</div>
</div>You will obtain the following output in the browser:
File name: blog-home.component.html
Live link: http://bit.ly/2TjT1FQ
File name: view-post.component.ts
Live link: http://bit.ly/2VqoaoB
Create a service file for blog post articles by running the following command:
ng generate service service/article
Update app.module.ts file by importing the provider for ArticleService using the following code:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { BlogHomeComponent } from './blog-home/blog-home.component';
import { HeaderComponent } from './header/header.component';
import { FooterComponent } from './footer/footer.component';
import { ArticleService } from './service/article.service';
import { HttpClientModule } from '@angular/common/http';
import { ViewPostComponent } from './view-post/view-post.component';
import { TitleHeaderComponent } from './title-header/title-header.component';
@NgModule({
declarations: [
AppComponent,
BlogHomeComponent,
HeaderComponent,
FooterComponent,
ViewPostComponent,
TitleHeaderComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [ArticleService],
bootstrap: [AppComponent]
})
export class AppModule { }Write the interface class in a newly created posts.ts file using the following code:
export interface Post {
photo: string;
title: string;
body: string;
tag: string;
}Import the Injectable, HttpClient, Post, and Observable modules using the following code:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Post } from '../posts'
import { Observable } from 'rxjs';Declare Url variables and assign string values in the ArticleService class as shown:
articlesUrl = 'http://localhost:3000/articles'; articleUrl = 'http://localhost:3000/article/'; article: any; httpOptions:any;
Inject HttpClient and set HttpHeaders using the following code:
constructor(private http: HttpClient) {
this.httpOptions = new HttpHeaders({
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Methods':'PUT, POST, GET, DELETE, OPTIONS',
});
}Write the CRUD service functions:
getArticles(): Observable<Post> {
this.article = this.http.get<Post>(this.articlesUrl);
return this.article;
}
getArticle(id: number) {
return this.http.get(this.articleUrl + id);
}
/** POST: add a new article to the database */
PostArticle(article: Post): Observable<Post> {
return this.http.post<Post>(this.articlesUrl,
{ 'title': article.title, 'body': article.body, 'tag': article.tag, 'photo': article.photo }, {
headers: this.httpOptions
})
}
deleteArticle(id: number):
Observable<{}> {
return this.http.delete(this.articleUrl + id, {
headers: this.httpOptions
})
}
updateArticle(id: number, article: Post): Observable<Post> {
return this.http.put<Post>(this.articleUrl + id, { 'title': article.title, 'body': article.body, 'tag': article.tag, 'photo': article.photo },{
headers: this.httpOptions
})
}
}Update the blog-home components class file with the following code:
import { Component, OnInit } from '@angular/core';
// Import service
import { ArticleService } from '../service/article.service';
@Component({
selector: 'app-blog-home',
templateUrl: './blog-home.component.html',
styleUrls: ['./blog-home.component.css']
})
export class BlogHomeComponent implements OnInit {
articles:any=[];
//Inject service
constructor(private articleService:ArticleService) { }
ngOnInit() {
this.articleService.getArticles()
.subscribe(
res => {
for(let key in res){
this.articles.push(res[key]);
}
},
err => {
console.log("Error occured");
}
);
}
}Update the blog-home components template file with the following code:
<app-title-header></app-title-header>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="row blog_posts stander_blog">
<div class="col-md-6 col-lg-4" *ngFor="let article of //[…]
</div>
</div>
</div>
</div>Update the root component template with the following code:
<div id="main-content" class="bg-color-gray">
<app-header></app-header>
<div class="page-container scene-main scene-main--fade_In">
<app-blog-home></app-blog-home>
<app-footer></app-footer>
</div>
</div>Run ng serve -o on the command line to view the following output:

Figure 3.18: Blog-home page of the application
Update the view-post components class file with the following code:
import { Component, OnInit } from '@angular/core';
import { ArticleService } from '../service/article.service';
@Component({
selector: 'view-post',
templateUrl: './view-post.component.html',
styleUrls: ['./view-post.component.css']
})
export class ViewPostComponent implements OnInit {
id: any;
article: any;
constructor( private articleService: ArticleService) { }
ngOnInit() {
this.id = '5b9426b70e473447f400eeb9' // id of first post from API
this.articleService.getArticle(this.id)
.subscribe(
res => {
console.log(res)
this.article = res;
},
err => {
console.log("Error occured");
}
);
}
}Update the view-post components template file with the following code:
<div class="page-container scene-main scene-main--fade_In">
<!-- Blog post -->
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="post_img">
<img src="https://{{article.photo}}" alt="Card image cap">
//[…]
</div>
</div>
</div>
</div>
</div>Update the root component template with the following code:
<div id="main-content" class="bg-color-gray">
<app-header></app-header>
<div class="page-container scene-main scene-main--fade_In">
<view-post></view-post>
<app-footer></app-footer>
</div>
</div>Run ng serve -o to start the application. You should obtain the following output:

Figure 3.19: View-post page of the application
File name: packt-student-reactive-form.component.html
Live link: http://bit.ly/2WutecX
Create an Angular CLI application named Reactive form:
ng new reactive-form
Create a component and name it PacktStudentReactiveForm:
ng generate component reactive-form/ PacktStudentReactiveForm
Register the reactive forms module in app.module.ts and add it to import properties to activate the reactive form using the following code:
import { ReactiveFormsModule } from '@angular/forms';
import { FormsModule } from '@angular/forms';
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule
],Import the FormControl and FormGroup modules into the reactive form component (packt-student-reactive-form.component.ts):
import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
import { Component, OnInit } from '@angular/core';Declare and initialize the array in the reactive components class, as follows:
courseTitles = ['MEAN Stack', 'MEVN Stack', 'MERN Stack'];
Create FormGroup and FormControl variable instances:
myform : FormGroup;
name : FormControl;
courseTitle : FormControl;
duration : FormControl;
constructor() { }Create functions to initialize and validate using the following code:
ngOnInit() {
this.createFormControls();
this.createForm();
}
createFormControls() {
this.name = new FormControl('Paul Adams', Validators.required),
this.courseTitle = new FormControl(this.courseTitles[0], Validators.required),
this.duration = new FormControl('6 days')
}
createForm() {
this.myform = new FormGroup({
name: this.name,
courseTitle : this.courseTitle,
duration: this.duration
});
}
submitted = false;
onSubmit() { this.submitted = true; console.log(this.name) }
newStudent() {
this.myform.reset();
}Register the control and form group in the html form template of the reactive component (packt-student-reactive-form.component.html) using the following code:
<div class="container">
<div *ngIf="!submitted">
<h1>Packt Course Form</h1>
//[…]
</select>
<div *ngIf="courseTitle.invalid" class="alert alert-danger">
courseTitle is required
</div>
</div>
<div class="form-group">
<label for="duration">Course Duration</label>
<input type="text" class="form-control" id="duration" formControlName="duration">
</div>
<button type="submit" class="btn btn-success" [disabled]="">Submit</button>
<button type="button" class="btn btn-default" (click)="newStudent();">New Student</button>
</form>
</div>Add a submitted view to the template:
<div *ngIf="submitted">
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-xs-3">Name</div>
<div class="col-xs-9 pull-left">{{name.value}}</div>
</div>
<div class="row">
<div class="col-xs-3">Course Duration</div>
<div class="col-xs-9 pull-left">{{duration.value}}</div>
</div>
<div class="row">
<div class="col-xs-3">Packt Course Title</div>
<div class="col-xs-9 pull-left">{{courseTitle.value}}</div>
</div>
<br>
<button class="btn btn-primary" (click)="submitted=false">Edit</button>
</div>
</div>Update the components style sheet (packt-student-reactive-form.component.css) and the main application style sheet (style.css) using the following code:
// packt-student-reactive-form.component.css
.ng-valid[required],
.ng-valid.required,
.has-success {
/* border-left: 5px solid #42A948; */
/* green */
}
.ng-invalid:not(form) {
/* border: 1px solid #a94442; */
/* red */
}
// style.css
/* You can add global styles to this file, and also import other style files */
@import url('https://unpkg.com/[email protected]/dist/css/bootstrap.min.css');Update the root template file (app.componets.html file) by hosting the form component src/app/app.component.html using the following code:
src/app/app.component.html < app-packt-student-reactive-form ></ app-packt-student-reactive-form >
Launch the application by running the following snippet in the command-line terminal and go to the address localhost:4200:
ng serve --open
You will obtain the following output:

Figure 3.20: Reactive/model-driven form
File name: login.component.html
Live link: http://bit.ly/2B8XFfK
Update the app component template with the following snippet and run ng serve to view the User Login form output:
File name: register.component.html
Live link: http://bit.ly/2Wul1p2
File name: create.component.html
Live link: http://bit.ly/2HGg3SD
Create the User Login form component using the following code:
ng generate component login
Update the User Login form component class and update the HTML template to be reactive/model-driven using the following code:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
@Component({
selector: 'login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
loginForm: FormGroup;
displayMessage: string;
submitted = false;
constructor(private formBuilder: FormBuilder) {
/* Declare Reactive Form Group here */
this.loginForm = this.formBuilder.group({
email: ['', [
Validators.required,
Validators.pattern("[^ @]*@[^ @]*")
]],
password: ['', [
Validators.minLength(8),
Validators.required
]],
});
}
submitForm() {
this.submitted = true;
/* Change the display message on button click / submit form */
if (this.loginForm.valid) {
this.loginUser();
}
}
loginUser() {
console.log('Logged In sucessfully')
}
}The template is updated with the following:
<title-header></title-header>
<div class="" style="padding-bottom: 3rem!important;">
<div class="row">
<div class="col-md-6 mx-auto">
<!-- form card login -->
<div class="card rounded-0">
//[…]
<!-- /form card login -->
</div>
</div>
</div><div id="main-content" class="bg-color-gray">
<app-header></app-header>
<div class="page-container scene-main scene-main--fade_In">
<app-login></app-login>
<app-footer></app-footer>
</div>
</div>You will obtain the following output once you type http://localhost:4200/login in the browser:

Figure 3.21: Reactive login form
Create the User Registration form component:
ng generate component register
Create an exportable user class file in the app directory using the following code:
export class Users {
constructor(
public fullName: string,
public email: string,
public password: string
) { }
}Update the User Registration form component class and update the HTML template to be template-driven.
The class is updated as follows:
import { Component, OnInit } from '@angular/core';
import { Users } from '../users';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
model = new Users('', '', '');
constructor(/*private auth: AuthService,
private router: Router*/) { }
ngOnInit() {
}
onSubmit() {
this.registerUser();
}
registerUser() {
console.log('Registration Successful')
}The template is updated as follows:
<title-header></title-header>
<div>
<div class="row">
<div class="col-md-6 mx-auto">
<!-- form card login -->
<div class="card rounded-0">
<h3 class="mb-0" style="text-align:center">Register Admin User</h3>
<div class="card-header">
</div>
<div class="card-body">
<form (ngSubmit)="userForm.form.valid && onSubmit()"
//[…]
<!-- /form card login -->
</div>
</div>
</div>Update the app component template with the following snippet and run ng serve to view the User Registration form output:
<div id="main-content" class="bg-color-gray">
<app-header></app-header>
<div class="page-container scene-main scene-main--fade_In">
<app-register></app-register>
<app-footer></app-footer>
</div>
</div>You will obtain the following output once you run http://localhost:4200/register in the browser:

Figure 3.22: Template-driven Register form
Create the Post Create/Edit form component and an exportable Posts class:
ng generate component create
export class Posts {
constructor(
public title: string,
public body: string,
public tag: string,
public photo: string,
) { }
}Update the Post Create/Edit form component class and update the HTML template to be template-driven.
The class is updated as follows:
import { Component, OnInit } from '@angular/core';
import { Posts } from '../post';
@Component({
selector: 'app-create',
templateUrl: './create.component.html',
styleUrls: ['./create.component.css']
})
export class CreateComponent implements OnInit {
tags = ['POLITICS', 'ECONOMY', 'EDUCATION','STORY','TECH'];
model = new Posts('','','','');
submitted = false;
constructor() { }
onSubmit() {
this.submitted = true;
console.log(this.model)
}
ngOnInit() {
}
}The template is updated as follows:
<title-header></title-header>
<div class="py-5">
<div class="row">
<div class="col-md-6 mx-auto">
<!-- form card login -->
<div class="card rounded-0">
<h3 style="text-align:center" class="mb-0">Create Post</h3>
<div class="card-header">
</div>
<div class="card-body">
<form (ngSubmit)="postForm.form.valid && onSubmit()"
//[…]
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>
<!--/card-block-->
</div>
<!-- /form card login -->
</div>
</div>
</div>Update the app component template with the following snippet and run ng serve to view the Post Create/Edit form output:
<div id="main-content" class="bg-color-gray">
<app-header></app-header>
<div class="page-container scene-main scene-main--fade_In">
<app-create></app-create>
<app-footer></app-footer>
</div>
</div>You will obtain the following output once you type http://localhost:4200/create in the browser window:

Figure 3.23: Template-driven post create/edit form
File name: blog-home.component.html
Live link: http://bit.ly/2CSjEaQ
Import RouterModule into the app module file (app.module.ts) and update the import property:
import { RouterModule, Routes } from '@angular/router';
imports: [
BrowserModule,
HttpClientModule,
RouterModule.forRoot(appRoutes),
FormsModule,
ReactiveFormsModule,
BrowserAnimationsModule
],Configure the route in app.module.ts as follows:
const appRoutes: Routes = [
{ path: 'blog', component: BlogHomeComponent,
data: { title: 'Article List' }},
{ path: 'blog/post/:id', component: ViewPostComponent },
{ path: 'login', component: LoginComponent},
{ path: 'register', component: RegisterComponent},
{ path: 'create', component: CreateComponent},
{ path: '',
redirectTo: '/blog',
pathMatch: 'full'
},
// { path: '**', component: PageNotFoundComponent }
];Add router-outlet to the app.component.html file:
<div id="main-content" class="bg-color-gray">
<app-header></app-header>
<div class="page-container scene-main scene-main--fade_In">
<router-outlet></router-outlet>
<app-footer></app-footer>
</div>
</div>Add the router link to the blog-home component:
<title-header></title-header>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="row blog_posts stander_blog">
<div class="col-md-6 col-lg-4" *ngFor="let article of articles">
<article>
<a routerLink="post/{{article._id}}">
<div class="post_img card-blog-img">
<img src="https://{{article.photo}}"
//[…]
</div>
</div>
</div>
</div>Start the server and serve the Angular application using the CLI with the following commands:
> node server.js > ng serve -o
Open the browser and input http://localhost:4200/blogin in the URL address bar to view the router in action.
You will obtain the following output:

Figure 3.24: Blog post route
If you click on one of the posts, it will navigate to the view-post page, as shown:

Figure 3.25: Route to view-post page
Change the font size
Change margin width
Change background colour