Project Details
We will create CMS For Blog Website using MongoDB, ExpressJS, Angular, and NodeJS. We will use Express and NodeJS for Web API and MongoDB for the database. We will use Admin Panel and frontend on both side features.
Coding Technologies
Backend API: Express, Nodejs
Database: MongoDB
Frontend: Angular
User Feature
- Register
- Login / Logout
- Add Article
- View Article
Admin Feature
- Admin Panel for Article CRUD Operation (Add / Edit /Delete)
- Article Category (Add /Edit /Delete)
- Option to make Article Featured
- User Management
- Article Approval
Fronted Features
- Article Listing Page
- Article Details Page
- Display Article as Featured, Latest Article, Category Wise
- Static Pages: About Us, Contact US, Contact Form
Installing & Integrate Bootstrap in project
2 3 4 |
npm install bootstrap |
Create Project Modules & Component
Let’s create project Module:
2 3 4 |
ng g module articles |
2 3 4 |
ng g module admin |
2 3 4 |
ng g module middleware |
2 3 4 |
ng g module staticpages |
Let’s create Articles Modules:
2 3 4 |
ng g component articles/article-list |
2 3 4 |
ng g component articles/article-details |
2 3 4 |
ng g component articles/latest-articles |
2 3 4 |
ng g component articles/featured-articles |
2 3 4 |
ng g component articles/categories |
Let’s create service for article module:
2 3 4 |
ng g service articles/articles |
Let’s create Components :
2 3 4 |
ng g component header |
2 3 4 |
ng g component footer |
2 3 4 |
ng g component banner |
2 3 4 |
ng g component pagenotfound |
Let’s create components of staticpages module:
2 3 4 |
ng g component staticpages/about-us |
2 3 4 |
ng g component staticpages/contact-us |
Let’s create service for staticpages module
2 3 4 |
ng g service staticpages/staticpages |
Step-1: Open app.module.ts
open your app.module.ts to import articles and static pages module and paste the below code
2 3 4 5 6 7 8 9 10 11 12 |
... import { ArticlesModule } from './articles/articles.module'; import { StaticpagesModule } from './staticpages/staticpages.module'; imports: [ .... ArticlesModule, StaticpagesModule ], |
Step-2: Open articles/articles.module.ts
open your articles/articles.module.ts to export the LatestArticleComponent component for showing this component on the root component app.component.html
2 3 4 5 6 7 8 9 10 |
... import { LatestArticlesComponent } from './latest-articles/latest-articles.component'; imports: [ CommonModule ], exports:[LatestArticlesComponent] |
Step-3: app.component.html
Create Home page layout structure
2 3 4 5 6 7 |
<app-header></app-header> <app-banner></app-banner> <app-latest-article></app-latest-article> <app-footer></app-footer> |
Theme Integration
styles.css
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
/* You can add global styles to this file, and also import other style files */ h1 {font-size: 2.4rem;margin-bottom: 30px;} .bg-blue {background-color:#79ce1d;} .navbar-brand img { height:30px; } .navbar-dark .navbar-nav .nav-link {color:#fff;} .navbar-dark .navbar-nav .active .nav-link {color:#fff;} .banner img {width:100%;} .title-heading{clear: both; width: 100%;padding: 10px;text-align: center;margin-bottom: 20px;} .blog-box {text-align: center; margin-bottom: 20px;padding: 10px; border: 1px solid #f7f7f7; box-shadow: 0px 2px 2px 1px #f6f6f6; } .blog-box h3 { margin:20px 0; font-size:22px; color:#000;} .blog-box p { color:#666; } .blog-box span, .posted-on span { font-style: italic; color:#000; } .blog-box img { width:100%; } .mtb-40 { margin:40px 0; min-height:450px;} .banner-box {position: relative;} .intro-text { width:100%; position: absolute; top:30%; text-align: center; color:#fff;} .intro-text-box { width: 62%;margin: auto;background-color: rgba(96, 96, 96, 0.6);padding: 20px;border: 10px solid #808080;} .intro-text-box h1 {font-size:3em;} .blog-right h3 {background-color:#000;color: #fff; padding:5px 15px;font-size:20px;} .detail-img {margin:40px 0px;} .rb-box-img { margin-right:15px; } .rb-box-img img { width:100px;} .rb-box {display: flex;} .rb-box-desc h4 {font-size:20px;color:#000;font-weight: 600;} .rb-box-desc p {color:#666;} .rb-box {margin-bottom:10px;} .recent-post a:hover {text-decoration: none;} .recent-post a:hover h4 {color:#007EDB;} .categories {margin-top:20px;} .categories ul {padding:0;margin:0; list-style: none;} .categories ul li { border-bottom:1px dotted #ccc; padding:5px 0px; } .categories ul li a {color:#333; display: block;} .categories ul li a:hover {color:#007EDB; text-decoration: none;} .body-content { min-height:380px; } .error-404 { text-align: center; } .error-404 h1{ font-size:10em; } .service-error {text-align:center; padding:50px 0;} .service-error h1 { font-size: 3em;text-transform: uppercase;color:#007EDA;} /* For Admin*/ .login-box {box-shadow: 1px 1px 7px #666;padding:20px;margin-top:10%;} .login-box h1 {font-size:24px;text-align: center;margin-bottom: 20px} .dash-left ul {padding:0;margin:0;list-style:none;} .dash-left ul li { background-color: #f1f1f1; margin-bottom:5px;} .dash-left ul li a {color:#333; padding:5px 15px; display: block;} .dash-left ul li:hover a {background-color:#007EDB; text-decoration: none; color:#fff;} .dash-left ul li a.active {background-color:#007EDB; color:#fff;} .dash-header {display:flex; justify-content: space-between;} .table img { width:80px; } footer {background-color: #000;color:#fff; padding:20px;} /* For validation*/ .ng-valid[required], .ng-valid.required {border: 1px solid #42A948;} .error {color:#ff0000;} .success { color:green; } .contact-message { text-align: center; } @media (max-width: 767px) { .intro-text {display: none;} } |
header.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<nav class="navbar navbar-expand-md navbar-dark bg-blue"> <div class="container"> <a class="navbar-brand" href="index.html"> <img src="assets/images/logo.png" alt="Angular Project"> </a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" (click)="toggleNavbarCollapsing()" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" [class.collapse]="navbarCollapsed" id="navbarCollapse"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Home</a> </li> <li class="nav-item"> <a class="nav-link" href="#">About Us</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Articles</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Contact Us</a> </li> </ul> <ul class="navbar-nav ml-auto"> <li class="nav-item"> <a class="nav-link" href="#">Login</a> </li> </ul> </div> </div> </nav> |
header.component.ts
2 3 4 5 6 7 8 |
navbarCollapsed = true; toggleNavbarCollapsing() { this.navbarCollapsed = !this.navbarCollapsed; } |
banner.component.html
2 3 4 5 6 7 8 9 10 11 |
<section class="banner"> <div class="banner-box"> <div class="intro-text"> </div> <img src="assets/images/blog-banner.jpeg" alt="banner"> </div> </section> |
latest-articles.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
<section class="featured-blog mtb-40"> <div class="container"> <div class="row"> <h2 class="title-heading">Latest Articles</h2> <div class="col-md-4"> <div class="blog-box"> <img src="assets/images/img1.jpeg" alt="blog1"> <h3>How to add Shopify Announcement bar (without an app)</h3> <p>by <span>Pradeep Maurya</span></p> <p>The Shopify announcement bar is an excellent way to promote a special discount offer, a sale, or another type of promotion at the top of your Shopify store. And there’s no need to pay a monthly fee for this feature. Simply paste a few lines of code into your theme and you’re done..</p> <a href="#" class="btn btn-primary">Read more...</a> </div> </div> <div class="col-md-4"> <div class="blog-box"> <img src="assets/images/img2.png" alt="blog1"> <h3>Transpilation in Angular</h3> <p>by <span>Pradeep Maurya</span></p> <p>Transpilation = translate + compilation The Angular compiler translates the html template to super optimized JavaScript code. The typescript compiler compiles typescript code into JavaScript. Also Read: Difference between JavaScript and TypeScript: JavaScript vs Typescript Transpiling..</p> <a href="#" class="btn btn-primary">Read more...</a> </div> </div> <div class="col-md-4"> <div class="blog-box"> <img src="assets/images/img3.jpeg" alt="post1"> <h3>Difference between JavaScript and TypeScript</h3> <p>by <span>Pradeep Maurya</span></p> <p>What is JavaScript? JavaScript is an object-based scripting language. JavaScript is the most popular programming language of HTML. It helps you to create interactive web pages which is lightweight and cross-platform. JavaScript is not designed for..</p> <a href="detail.html" class="btn btn-primary">Read more...</a> </div> </div> <div class="col-md-4"> <div class="blog-box"> <img src="assets/images/img4.jpg" alt="post2"> <h3>How to use cookies in angular</h3> <p>by <span>Pradeep Maurya</span></p> <p>What is Cookies in Angular? Cookies are small packages of information that can be temporarily stored/saved by your browser and websites which are using cookies for multiple things. Cookies are used in multiple requests and browser sessions and can store..</p> <a href="detail.html" class="btn btn-primary">Read more...</a> </div> </div> <div class="col-md-4"> <div class="blog-box"> <img src="assets/images/img5.jpeg" alt="post3"> <h3>How to Get Current Visitor Location using HTML5 Geolocation API</h3> <p>by <span>Pradeep Maurya</span></p> <p>This feature Get Current Visitor Location helps to provide the website visitor with a better browsing experience. For instance, you can return search results which are close to the location of the user..</p> <a href="detail.html" class="btn btn-primary">Read more...</a> </div> </div> <div class="col-md-4"> <div class="blog-box"> <img src="assets/images/img6.jpeg" alt="post4"> <h3>What is MERN Stack?</h3> <p>by <span>Pradeep Maurya</span></p> <p>In the world of software development, MERN Stack is one of the most widely used technological stacks and a web development framework. we can create simple as well complex web applications using MERN (MongoDB, ExpressJS, ReactJS, and NodeJS)...</p> <a href="detail.html" class="btn btn-primary">Read more...</a> </div> </div> </div> </div> </section> |
footer.component.html
2 3 4 5 6 7 8 9 10 |
<footer> <div class="container"> <div class="copyright"> <div>Powered by: Tutorialswebsite.com</div> </div> </div> </footer> |
Home Page Layout
Routing Configuration
App Routing Module Configuration
Edit the file src/app/app-routing.module.ts
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import {PagenotfoundComponent} from './pagenotfound/pagenotfound.component' const routes: Routes = [ {path:'',redirectTo:'',pathMatch:'full'}, {path:'**',component:PagenotfoundComponent} ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } } |
articles-routing.module.ts Configuration
create the file articles-routing.module.ts in folder src/app/articles/
Edit the file src/app/courses/articles-routing.module.ts
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import {ArticleListComponent} from './article-list/article-list.component'; import {ArticleDetailsComponent} from './article-details/article-details.component'; const routes: Routes = [ {path:'article',component:ArticleListComponent}, {path:'article/:id',component:ArticleDetailsComponent} ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class ArticlesRoutingModule { } |
staticpages-routing.module.ts Configuration
create the file staticpages-routing.module.ts in folder src/app/staticpages/
Edit the file src/app/staticpages/staticpages-routing.module.ts
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import {AboutUsComponent} from './about-us/about-us.component'; import {ContactUsComponent} from './contact-us/contact-us.component'; const routes: Routes = [ {path:'about-us', component:AboutUsComponent}, {path:'contact-us',component:ContactUsComponent} ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class StaticpagesRoutingModule { } |
Home Page Banner & Feature Article Routing
To set banner and featured view on the home page only. you just need to edit the below file
Edit the file src/app/app.component.ts
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import { Component } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { constructor(public router:Router){} title = 'mean-project'; } |
Edit the file src/app/app.component.html
2 3 4 5 6 7 8 |
<app-header></app-header> <app-banner *ngif="router.url == '/'"></app-banner> <app-latest-articles *ngif="router.url == '/'"></app-latest-articles> <router-outlet></router-outlet> <app-footer></app-footer> |
Header Navigation
Set the routerLink and routerLinkActive in header component in menu link
src/app/header/header.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<nav class="navbar navbar-expand-md navbar-dark bg-blue"> <div class="container"> <a class="navbar-brand" href="index.html"> <img src="assets/images/logo.png" alt="Angular Project"> </a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" (click)="toggleNavbarCollapsing()" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" [class.collapse]="navbarCollapsed" id="navbarCollapse"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" routerlink="/" routerlinkactive="active">Home</a> </li> <li class="nav-item"> <a class="nav-link" routerlink="/about-us" routerlinkactive="active">About Us</a> </li> <li class="nav-item"> <a class="nav-link" routerlink="/article" routerlinkactive="active">Articles</a> </li> <li class="nav-item"> <a class="nav-link" routerlink="/contact-us" routerlinkactive="active">Contact Us</a> </li> </ul> <ul class="navbar-nav ml-auto"> <li class="nav-item"> <a class="nav-link" href="#">Login</a> </li> </ul> </div> </div> </nav> |
Article Listing and Inner Page Design
Article listing page Design
Edit the file src/app/articles/article-list/article-list.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
<section class="blog-list mtb-40"> <div class="container"> <h1>Article List</h1> <div class="row"> <div class="col-md-8"> <div class="col-md-12"> <div class="blog-box"> <div class="row"> <div class="col-md-4"> <img src="assets/images/img1.jpeg" alt="blog1"> </div> <div class="col-md-8"> <h3>How to add Shopify Announcement bar (without an app)</h3> <p>by <span>Pradeep Maurya</span></p> <p>The Shopify announcement bar is an excellent way to promote a special discount offer, a sale, or another type of promotion...</p> <a href="/article/1" class="readmore">Read more...</a></div> </div> </div> </div> <div class="col-md-12"> <div class="blog-box"> <div class="row"> <div class="col-md-4"> <img src="assets/images/img2.png" alt="blog1"> </div> <div class="col-md-8"> <h3>Transpilation in Angular</h3> <p>by <span>Pradeep Maurya</span></p> <p>Transpilation = translate + compilation The Angular compiler translates the html template to super optimized JavaScript code...</p> <a href="/article/2" class="readmore">Read more...</a></div> </div> </div> </div> <div class="col-md-12"> <div class="blog-box"> <div class="row"> <div class="col-md-4"> <img src="assets/images/img3.jpeg" alt="blog1"> </div> <div class="col-md-8"> <h3>Difference between JavaScript and TypeScript</h3> <p>by <span>Pradeep Maurya</span></p> <p>What is JavaScript? JavaScript is an object-based scripting language. JavaScript is the most popular programming language of HTML...</p> <a href="/article/3" class="readmore">Read more...</a></div> </div> </div> </div> <div class="col-md-12"> <div class="blog-box"> <div class="row"> <div class="col-md-4"> <img src="assets/images/img4.jpg" alt="blog1"> </div> <div class="col-md-8"> <h3>How to use cookies in angular</h3> <p>by <span>Pradeep Maurya</span></p> <p>What is Cookies in Angular? Cookies are small packages of information that can be temporarily stored/saved by your browser ...</p> <a href="/article/4" class="readmore">Read more...</a></div> </div> </div> </div> <div class="col-md-12"> <div class="blog-box"> <div class="row"> <div class="col-md-4"> <img src="assets/images/img5.jpeg" alt="blog1"> </div> <div class="col-md-8"> <h3>How to Get Current Visitor Location using HTML5 Geolocation API</h3> <p>by <span>Pradeep Maurya</span></p> <p>This feature Get Current Visitor Location helps to provide the website visitor with a better browsing experience...</p> <a href="/article/5" class="readmore">Read more...</a></div> </div> </div> </div> <div class="col-md-12"> <div class="blog-box"> <div class="row"> <div class="col-md-4"> <img src="assets/images/img6.jpeg" alt="blog1"> </div> <div class="col-md-8"> <h3>What is MERN Stack?</h3> <p>by <span>Pradeep Maurya</span></p> <p>In the world of software development, MERN Stack is one of the most widely used technological stacks and a web development framework...</p> <a href="/article/6" class="readmore">Read more...</a></div> </div> </div> </div> </div> <div class="col-md-4"> <app-featured-articles></app-featured-articles> <app-categories></app-categories> </div> </div> </div> </section> |
Featured Article Right Widget Design
Edit the file src/app/articles/featured-articles/featured-articles.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
<div class="widget right-widget recent-post"> <h4 class="widget-title">Featured Posts</h4> <a href="/article/1"> <div class="rb-box"> <div class="rb-box-img"> <img src="assets/images/img1.jpeg" alt="blog1"> </div> <div class="rb-box-desc"> <h5>How to add Shopify Announcement bar (without an app)</h5> <p>by <span>Pradeep Maurya</span></p> <p>Posted On: March 10, 2019</p> </div> </div> </a> <a href="/article/2"> <div class="rb-box"> <div class="rb-box-img"> <img src="assets/images/img2.png" alt="blog1"> </div> <div class="rb-box-desc"> <h5>Transpilation in Angular</h5> <p>by <span>Pradeep Maurya</span></p> <p>Posted On: March 10, 2019</p> </div> </div> </a> <a href="/article/3"> <div class="rb-box"> <div class="rb-box-img"> <img src="assets/images/img3.jpeg" alt="blog1"> </div> <div class="rb-box-desc"> <h5>Difference between JavaScript and TypeScript</h5> <p>by <span>Pradeep Maurya</span></p> <p>Posted On: March 10, 2019</p> </div> </div> </a> <a href="/article/4"> <div class="rb-box"> <div class="rb-box-img"> <img src="assets/images/img4.jpg" alt="blog1"> </div> <div class="rb-box-desc"> <h5>How to use cookies in angular</h5> <p>by <span>Pradeep Maurya</span></p> <p>Posted On: March 10, 2019</p> </div> </div> </a> <a href="/article/5"> <div class="rb-box"> <div class="rb-box-img"> <img src="assets/images/img5.jpeg" alt="blog1"> </div> <div class="rb-box-desc"> <h5>How to Get Current Visitor Location using HTML5 Geolocation API</h5> <p>by <span>Pradeep Maurya</span></p> <p>Posted On: March 10, 2019</p> </div> </div> </a> </div> |
Article Categories List Widget Design
Edit the file src/app/articles/categories/categories.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<div class="widget right-widget categories"> <h3 class="widget-title">Popular Categories</h3> <ul> <li><a href="#">Angular 7</a></li> <li><a href="#">Python</a></li> <li><a href="#">MVC 4</a></li> <li><a href="#">Angular Material</a></li> <li><a href="#">SQL Server</a></li> <li><a href="#">Entity Framework</a></li> <li><a href="#">ASP.Net</a></li> <li><a href="#">CSS 3</a></li> <li><a href="#">TypeScript</a></li> <li><a href="#">Java</a></li> </ul> </div> |
Add css for article lists and right widget
Edit the file src/styles.css and insert below css code
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
.blog-list .blog-box{ text-align: left; } .blog-list .blog-box h3 { margin: 5px 0; font-size: 22px; color: #000; } .blog-list .blog-box p{ margin-bottom: 5px; } .blog-list .blog-box .readmore{ color:blue; } .widget{text-align: left; margin-bottom: 20px;padding: 15px; border: 1px solid #f7f7f7; box-shadow: 0px 2px 2px 1px #f6f6f6;} .widget p{margin-bottom: 5px;} .widget a{text-decoration: none;} .widget .rb-box{ border-bottom: 1px solid #f6f6f6; } .widget-title{ text-align: left; width: 100%; margin: 15px auto; display: inline-block; } .detail-img img{width:100%;} |
Article Details Page Design
Edit the file src/app/articles/article-details/article-details.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<section class="blog-detail mtb-40"> <div class="container"> <div class="row"> <div class="col-md-8"> <div class="blog-left"> <h1>How to add Shopify Announcement bar (without an app)</h1> <div class="posted-on"> <p>by <span>Pradeep Maurya</span> on <span>March 10, 2019</span></p> </div> <div class="detail-img"> <img src="assets/images/img1.jpeg" alt="blog1"> </div> <div class="blog-desc"> <p>The Shopify announcement bar is an excellent way to promote a special discount offer, a sale, or another type of promotion at the top of your Shopify store. And there’s no need to pay a monthly fee for this feature. Simply paste a few lines of code into your theme and you’re done. </p> <p> This free Shopify announcement bar also allows you to display an optional “free shipping countdown,” so customers can always see how close they are to receiving free shipping. </p> <p>Now these days eCommerce websites have many announcement. So they need to notify user about announcements. Like: – </p> <ul> <li>Highlight a recently released product</li> <li>Advertise a special or promotion</li> <li>Weather delay or holiday hours</li> <li>Promote upcoming new products</li> <li>Offer a free giveaway or download</li> <li>Share news about a recent award or certification</li> </ul> </div> </div> </div> <div class="col-md-4"> <app-featured-articles></app-featured-articles> <app-categories></app-categories> </div> </div> </div> </section> |
About Us Page Design
Edit the file src/app/staticpages/about-us/about-us.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<section class="blog-detail mtb-40"> <div class="container"> <div class="row"> <div class="col-md-12"> <div class="blog-left"> <h1>About Us</h1> <div class="detail-img"> <img src="assets/images/img1.jpeg" alt="blog1"> </div> <div class="blog-desc"> <p>The Shopify announcement bar is an excellent way to promote a special discount offer, a sale, or another type of promotion at the top of your Shopify store. And there’s no need to pay a monthly fee for this feature. Simply paste a few lines of code into your theme and you’re done. </p> <p> This free Shopify announcement bar also allows you to display an optional “free shipping countdown,” so customers can always see how close they are to receiving free shipping. </p> <p>Now these days eCommerce websites have many announcement. So they need to notify user about announcements. Like: – </p> <ul> <li>Highlight a recently released product</li> <li>Advertise a special or promotion</li> <li>Weather delay or holiday hours</li> <li>Promote upcoming new products</li> <li>Offer a free giveaway or download</li> <li>Share news about a recent award or certification</li> </ul> </div> </div> </div> </div> </div> </section> |
Contact Us Page Design
Edit the file src/app/staticpages/contact-us/contact-us.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
<section class="blog-detail mtb-40"> <div class="container"> <div class="row"> <div class="col-md-12"> <div class="blog-left"> <h1>Contact Us</h1> <div class="blog-desc"> <!--Section: Contact v.2--> <section class="mb-4"> <!--Section description--> <p class="text-center w-responsive mx-auto mb-5">Do you have any questions? Please do not hesitate to contact us directly. Our team will come back to you within a matter of hours to help you.</p> <div class="row"> <!--Grid column--> <div class="col-md-9 mb-md-0 mb-5"> <form id="contact-form" name="contact-form" action="mail.php" method="POST"> <!--Grid row--> <div class="row"> <!--Grid column--> <div class="col-md-6"> <div class="md-form mb-0"> <input type="text" id="name" name="name" class="form-control"> <label for="name" class="">Your name</label> </div> </div> <!--Grid column--> <!--Grid column--> <div class="col-md-6"> <div class="md-form mb-0"> <input type="text" id="email" name="email" class="form-control"> <label for="email" class="">Your email</label> </div> </div> <!--Grid column--> </div> <!--Grid row--> <!--Grid row--> <div class="row"> <div class="col-md-12"> <div class="md-form mb-0"> <input type="text" id="subject" name="subject" class="form-control"> <label for="subject" class="">Subject</label> </div> </div> </div> <!--Grid row--> <!--Grid row--> <div class="row"> <!--Grid column--> <div class="col-md-12"> <div class="md-form"> <textarea type="text" id="message" name="message" rows="2" class="form-control md-textarea"></textarea> <label for="message">Your message</label> </div> </div> </div> <!--Grid row--> </form> <div class="text-center text-md-left"> <a class="btn btn-primary" onclick="document.getElementById('contact-form').submit();">Send</a> </div> <div class="status"></div> </div> <!--Grid column--> <!--Grid column--> <div class="col-md-3 text-center"> <ul class="list-unstyled mb-0"> <li><i class="fas fa-map-marker-alt fa-2x"></i> <p>Delhi , India-110009</p> </li> <li><i class="fas fa-phone mt-4 fa-2x"></i> <p>+91-99999999</p> </li> <li><i class="fas fa-envelope mt-4 fa-2x"></i> <p>info@tutorialswebsite.com</p> </li> </ul> </div> <!--Grid column--> </div> </section> <!--Section: Contact v.2--> </div> </div> </div> </div> </div> </section> |
Create Express App for Backend API
MongoDB Atlas Connection & User Models Schema
Install Mongoose Package to connect MongoDB with Nodejs/Express
2 3 4 |
npm install mongoose |
Now we will create a models folder under the backend/api folder.
Next, we will create a user.js file to define MongoDB Atlas Connection and User Model Schema.
Edit the file backend/api/models/user.js
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
const mongoose = require('mongoose'); mongoose.connect('mongodb+srv://meanproject:<password>@clustermean.puxhx.mongodb.net/meanDatabase?retryWrites=true&w=majority', {useNewUrlParser: true}); var conn =mongoose.Collection; var userSchema =new mongoose.Schema({ name: String, email: String, password: String, }); var userModel = mongoose.model('Users', userSchema); module.exports=userModel; |
Please changes the database string with your MongoDB connection string.
Save User Records to MongoDB Cluster
Edit the file backend/api/routes/users.js
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
var express = require('express'); var userModel = require('../models/user'); var router = express.Router(); /* GET users listing. */ router.get('/', function(req, res, next) { var userDetails = new userModel({ name: 'Vikas', email: 'vikas@gmail.com', password: 'vikas@123', }); userDetails.save(function(err,req1){ if(err) throw err; res.render('index', { title: 'User Data Inserted' }); }) }); module.exports = router; |
Now open the URL: http://localhost:3000/users to insert user records
Create User Account Modules & Component
Create Account Module
2 3 4 |
ng g module account --routing |
Create Registration Component under account folder
2 3 4 |
ng g c account/registration |
Create Login Component under account folder
2 3 4 |
ng g c account/login |
Create service for account module
2 3 4 |
ng g service account/accountservice |
Create the design of registration page
Edit src/app/account/registration/registration.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<section class="Singup-wrap mtb-40"> <div class="container"> <div class="row justify-content-center"> <div class="col-md-6"> <div class="login-box"> <h1>User Registration</h1> <div class="alert alert-success" *ngif="datasaved"> {{massage}} </div> <form (ngsubmit)="onSubmit()" [formgroup]="regForm"> <div class="form-group form-row"> <label class="col-md-3">Name : <span class="required">*</span></label> <div class="col-md-9"> <input type="text" formcontrolname="Name" class="form-control" placeholder="Name" required=""> <span *ngif="!regForm.get('Name').valid && regForm.get('Name').touched">Please enter Your Name !!!</span> </div> </div> <div class="form-group form-row"> <label class="col-md-3">Email ID <span class="required">*</span></label> <div class="col-md-9"> <input type="text" formcontrolname="Email" class="form-control" placeholder="Email Id" required=""> <span *ngif="!regForm.get('Email').valid && regForm.get('Email').touched">Please enter Email !!!</span> </div> </div> <div class="form-group form-row"> <label class="col-md-3">Password <span class="required">*</span></label> <div class="col-md-9"> <input type="password" formcontrolname="Password" class="form-control" placeholder="Password" required=""> <span *ngif="!regForm.get('Password').valid && regForm.get('Password').touched">Please enter Password !!!</span> </div> </div> <div class="form-group"> <button type="submit" [disabled]="!regForm.valid" class="btn btn-primary">Submit</button> </div> </form> </div> </div> </div> </div> </section> |
Create a class as accountinfo
2 3 4 |
ng g class account/accountinfo |
Add/Edit the properties in the file src/app/account/accountinfo.ts
2 3 4 5 6 7 8 9 |
export class Accountinfo { Name:string; Email:string; Password:string; } |
Edit the properties in the file src/app/account/accountservice.service.ts
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import { Injectable } from '@angular/core'; import { HttpClient,HttpHeaders} from '@angular/common/http'; import {Observable} from 'rxjs'; import {Accountinfo} from './accountinfo' @Injectable({ providedIn: 'root' }) export class AccountserviceService { url='http://localhost:3000/' constructor(private http:HttpClient) { } createaccount(accinfo:Accountinfo):Observable<Accountinfo>{ return this.http.post<Accountinfo>(this.url+'api/register',accinfo) } } |
Edit the properties in the file src/app/account/registration/registration.component.ts
Import the FormBuilder, Validators, FormGroup from @angular/forms
Import the AccountserviceService service and Accountinfo Class
Inject FormBuilder and AccountserviceService in constructor
Set the Validators for all controls
Create the method for createuserAccount
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import { Component, OnInit } from '@angular/core'; import { FormBuilder, Validators, FormGroup } from '@angular/forms'; import {AccountserviceService} from '../accountservice.service'; import {Accountinfo} from '../accountinfo'; @Component({ selector: 'app-registration', templateUrl: './registration.component.html', styleUrls: ['./registration.component.css'] }) export class RegistrationComponent implements OnInit { regForm: FormGroup; datasaved = false; massage: string; constructor(private formbuilder: FormBuilder, private accountservice: AccountserviceService) { } ngOnInit() { this.setFormState(); } setFormState(): void { this.regForm = this.formbuilder.group({ Name: ['', [Validators.required]], Email: ['', [Validators.required]], Password: ['', [Validators.required]] }) } onSubmit() { let userinfo = this.regForm.value; //console.log(userinfo); this.createuserAccount(userinfo); this.regForm.reset(); } createuserAccount(accinfo:Accountinfo) { this.accountservice.createaccount(accinfo).subscribe( () => { this.datasaved = true; this.massage = "User Created"; this.regForm.reset(); } ) } } |
Edit the file src/app/app.module.ts
Import AccountserviceService and set it in provider array
Import HttpClientModule and set it in imports array
Import AccountModule and set it in provider array
import { HttpClientModule, HttpClient } from ‘@angular/common/http’; and set it in imports array
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import {AccountserviceService} from './account/accountservice.service'; import { HttpClientModule, HttpClient } from '@angular/common/http'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HeaderComponent } from './header/header.component'; import { FooterComponent } from './footer/footer.component'; import { BannerComponent } from './banner/banner.component'; import { PagenotfoundComponent } from './pagenotfound/pagenotfound.component'; import { ArticlesModule } from './articles/articles.module'; import { StaticpagesModule } from './staticpages/staticpages.module'; import {AccountModule} from './account/account.module'; @NgModule({ declarations: [ AppComponent, HeaderComponent, FooterComponent, BannerComponent, PagenotfoundComponent ], imports: [ BrowserModule, HttpClientModule, ArticlesModule, StaticpagesModule, AccountModule, AppRoutingModule, ], providers: [AccountserviceService], bootstrap: [AppComponent] }) export class AppModule { } |
Edit the file src/app/account/account.module.ts
import { FormsModule, ReactiveFormsModule } from ‘@angular/forms’;
Set ReactiveFormsModule it in imports array and FormsModule, ReactiveFormsModule in exports array
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { AccountRoutingModule } from './account-routing.module'; import { RegistrationComponent } from './registration/registration.component'; import { LoginComponent } from './login/login.component'; @NgModule({ declarations: [RegistrationComponent, LoginComponent], imports: [ CommonModule, AccountRoutingModule, ReactiveFormsModule ], exports: [ CommonModule, FormsModule, ReactiveFormsModule ] }) export class AccountModule { } |
Edit the file src/app/account/account-routing.module.ts
Create route path for register page and define the component which we want to load.
2 3 4 5 6 7 8 9 |
import {RegistrationComponent} from './registration/registration.component' const routes: Routes = [ {path:'register',component:RegistrationComponent}, ]; |
Create API in Backend to submit register form data using post method
Edit the file backend/api/app.js
define app.use(‘/api’, usersRouter); in app.js
Edit the file backend/api/routes/users.js
Now we will create new route “register” using post method.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
router.post('/register', function(req, res, next) { var userDetails = new userModel({ name: req.body.Name, email: req.body.Email, password: req.body.Password, }); userDetails.save().then(doc=>{ res.status(201).json({ message:"Inserted Successfully", results:doc }); }) .catch(err=>{ res.json(err); }); }); |
Access to XMLHttpRequest at ‘http://localhost:3000/api/register’ from origin ‘http://localhost:4200’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
Edit the file backend/api/app.js
Add the below code to app.js to resolve the CORS policy
2 3 4 5 6 7 8 9 10 11 12 |
app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header( "Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,Authorization" ); res.header('Access-Control-Allow-Methods', 'GET,PUT,PATCH,POST,DELETE,OPTIONS'); next(); }); |
Now test and submit the register page form data, you will get success response and data will insert into mongodb database.
User Model Schema or User table Schema Validation
Edit the file backend/api/models/user.js
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
var userSchema =new mongoose.Schema({ name: {type:String, required: true }, email: { type:String, required: true, index: { unique: true, }, match:/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/ }, password: { type:String, required: true }, date:{ type: Date, default: Date.now } }); |
How to resolve below warning message on backend
(node:10270) [MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
(node:10270) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
Solution:
You have to add {useCreateIndex: true, useUnifiedTopology: true} in MongoClient constructor. Please check the below code
2 3 4 5 6 |
const mongoose = require('mongoose'); mongoose.connect('mongodb connection string', {useNewUrlParser: true,useCreateIndex: true, useUnifiedTopology: true}); var conn =mongoose.Collection; |
Check Email Exists function
If you want to check the current user enter an email that already exists or is not in database before register an new account. We will add the below function in the route file and pass this function with register post route as middleware.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function checkEmail(req,res,next){ var email=req.body.Email; var checkexitemail=userModel.findOne({email:email}); checkexitemail.exec((err,data)=>{ if(err) throw err; if(data){ return res.status(200).json({ msg:"Email Already Exits", results:data }); } next(); }); } |
In the below code you can see, I am using checkEmail as middleware.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
router.post('/register',checkEmail,function(req, res, next) { var userDetails = new userModel({ name: req.body.Name, email: req.body.Email, password: req.body.Password, }); userDetails.save().then(resResult=>{ res.status(201).json({ msg:"Inserted Successfully", results:resResult }); }) .catch(err=>{ res.json(err); }); }); |
Now test and submit the register page form data, you will get success response and data will insert into mongodb database.
How to Enctypt User Password submitted with Registration Form
To encrypt the user registration form password, we will install the package named bcrypt and use this package to create a password hash to store into the database.
Let’s install the package bcrypt. Follow the below steps:
2 3 4 |
npm install bcrypt |
Now we have to import or require this package in our backed route file
Edit the file backend/api/routes/users.js
2 3 4 |
const bcrypt = require('bcrypt'); |
Now we have to do some changes to register post route
Copy the below and replace your current code with the below one
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
router.post('/register', checkEmail,function(req, res, next) { bcrypt.hash(req.body.Password, 10, function(err, hash) { if(err){ res.status(400).json({ msg:"Something Wrong, Try Later!", results:err }); }else{ var userDetails = new userModel({ name: req.body.Name, email: req.body.Email, password: hash, }); userDetails.save().then(resResult=>{ res.status(201).json({ msg:"Inserted Successfully", results:resResult }); }) .catch(err=>{ res.json(err); }); } }); }); |
In the above code, you will find
2 3 4 |
bcrypt.hash(req.body.Password, 10, function(err, hash) { |
In the code, you can see we are using bcrypt hash function to create a password hash and Salt length as 10 to generate or salt to use.
After replacing the code, just refresh your register page and submit the form.
Wow Now the password is showing encrypted format in the database.
User Login
Now we will see the complete step about the login form, login services, login route, show success, and error message.
So let’s start with the login form creation
Create user login form
Edit src/app/account/login/login.component.html
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<section class="Singup-wrap mtb-40"> <div class="container"> <div class="row justify-content-center"> <div class="col-md-6"> <div class="login-box"> <h1>User Login</h1> <div *ngif="status=='success'; else errorStatus"> <div class="alert alert-success" *ngif="datasaved"> {{message}} </div> </div> <ng-template #errorstatus=""> <div class="alert alert-danger" *ngif="datasaved"> {{message}} </div> </ng-template> <form (ngsubmit)="onSubmit()" [formgroup]="loginForm"> <div class="form-group form-row"> <label class="col-md-3">Email ID <span class="required">*</span></label> <div class="col-md-9"> <input type="text" formcontrolname="Email" class="form-control" placeholder="Email Id" required=""> <span *ngif="!loginForm.get('Email').valid && loginForm.get('Email').touched">Please enter Email !!!</span> </div> </div> <div class="form-group form-row"> <label class="col-md-3">Password <span class="required">*</span></label> <div class="col-md-9"> <input type="password" formcontrolname="Password" class="form-control" placeholder="Password" required=""> <span *ngif="!loginForm.get('Password').valid && loginForm.get('Password').touched">Please enter Password !!!</span> </div> </div> <div class="form-group"> <button type="submit" [disabled]="!loginForm.valid" class="btn btn-primary">Submit</button> </div> </form> </div> </div> </div> </div> </section> |
Create a class as userloginfo
2 3 4 |
ng g class account/userloginfo |
Add/Edit the properties in the file src/app/account/userloginfo.ts
2 3 4 5 6 7 |
export class Userloginfo { Email:string; Password:string; } |
Edit the properties in the file src/app/account/login/login.component.ts
Import the FormBuilder, Validators, FormGroup from @angular/forms
Import the AccountserviceService service and Userloginfo Class
Inject FormBuilder and AccountserviceService in the constructor
Set the Validators for all controls
Create the method for userlogin
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
import { Component, OnInit } from '@angular/core'; import { FormBuilder, Validators, FormGroup } from '@angular/forms'; import {AccountserviceService} from '../accountservice.service'; import {Userloginfo} from '../userloginfo'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { loginForm: FormGroup; datasaved = false; message: string; status:string; constructor(private formbuilder: FormBuilder, private accountservice: AccountserviceService) { } ngOnInit(): void { this.setFormState(); } setFormState(): void { this.loginForm = this.formbuilder.group({ Email: ['', [Validators.required]], Password: ['', [Validators.required]] }) } onSubmit() { let userinfo = this.loginForm.value; this.userLogin(userinfo); this.loginForm.reset(); } userLogin(logininfo:Userloginfo) { this.accountservice.userlogin(logininfo).subscribe( (resResult) => { let resp=JSON.stringify(resResult); console.log(resp); this.datasaved = true; this.message = resResult['msg']; this.status = resResult['status']; if(resResult['status']=='success'){ localStorage.setItem('Loginuser',resp) }else{ localStorage.removeItem('Loginuser'); } this.loginForm.reset(); } ) } } |
Edit the file src/app/account/account-routing.module.ts
Create a route path for the login page and define the component which we want to load.
2 3 4 5 6 7 8 9 |
import {LoginComponent} from './login/login.component'; const routes: Routes = [ {path:'login',component:LoginComponent}, ]; |
Add the properties in the file src/app/account/accountservice.service.ts
Import the Userloginfo Class and create userlogin service method to pass user login details
2 3 4 5 6 7 8 9 |
import {Userloginfo} from './userloginfo'; userlogin(logininfo:Userloginfo):Observable<Userloginfo>{ return this.http.post<Userloginfo>(this.url+'api/login',logininfo) } |
Create API in Backend to submit login form data using post method
Edit the file backend/api/routes/users.js
Now we will create a new route “login” using the post method.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
router.post("/login",function(req,res,next){ var email=req.body.Email; userModel.find({email:email}) .exec() .then(user=>{ if(user.length<1){ res.status(200).json({ msg:"Auth Failed", UserData:'', status:'error' }); }else{ bcrypt.compare(req.body.Password, user[0].password, function(err, result) { if(err){ res.json({ msg:"Auth Failed", UserData:'', status:'error' }); } if(result){ res.status(200).json({ msg:"User Login Successfully", UserData:user, status:'success' }); }else{ res.json({ msg:"Auth Failed", UserData:'', status:'error' }); } }); } }) .catch(err=>{ res.json({ error:err }); }) }); |
Add Login route to navigation menu
Now open the URL: http://localhost:3000/login and enter your user email and password
Define User Role
Here we will see about user roles like admin, author.
Find below code and update your backend user schema and define the default role with the new user account creation
Edit the file backend/api/models/user.js
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
var userSchema =new mongoose.Schema({ name: {type:String, required: true }, email: { type:String, required: true, index: { unique: true, }, match:/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/ }, password: { type:String, required: true }, role: { type:String, required: true }, date:{ type: Date, default: Date.now } }); var userModel = mongoose.model('Users', userSchema); module.exports=userModel; |
As in the above code, we define the new schema property as “role”.
Now we have to assign the predefined role value as “Author” at the time of the user registration.
Edit the file backend/api/routes/users.js
2 3 4 5 6 7 8 9 10 |
var userDetails = new userModel({ name: req.body.Name, email: req.body.Email, password: hash, role:'Author' }); |
In the above code, you can see, I defined static predefined value for role as “Autor”.
We will update this userDetails under the registration route. You can find the complete code below.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
router.post('/register', checkEmail,function(req, res, next) { bcrypt.hash(req.body.Password, 10, function(err, hash) { if(err){ res.status(400).json({ msg:"Something Wrong, Try Later!", results:err }); }else{ var userDetails = new userModel({ name: req.body.Name, email: req.body.Email, password: hash, role:'Author' }); userDetails.save().then(resResult=>{ res.status(201).json({ msg:"User Created Successfully", results:resResult }); }) .catch(err=>{ res.json(err); }); } }); }); |
Now you can test the functionality with new user registration.
Logout Function
Now we will work on the logout function after successfully loggedin.
Edit the file: src/app/header/header.component.html
Now we will add below logout code after the login link in the header.component.html file
2 3 4 5 6 |
<li class="nav-item" *ngif="isloggedin"> <button (click)="onLogout()">Logout</button> </li> |
In the above code, you can see the *ngIf condition to check the user is logged in or not. We will define the isloggedin default value as false in the header.component.ts file.
Edit the file: src/app/header/header.component.ts
First import the Router from “@angular/router”
2 3 4 |
import { Router } from "@angular/router"; |
Now we need to define the logout function as well as we need to assign the Router to a private variable using the constructor.
Also, we will define a custom variable isloggedin=false; to check user logged in or not
2 3 4 5 6 7 8 9 10 |
isloggedin=false; constructor( private router:Router) { if(localStorage.getItem('Loginuser')){ this.isloggedin=true; } } |
In the above code, you can find the if condition to check localStorage have “Login user” data or not. if the condition find true then we will assign isloggedin=true;
After the above code, we will define the logout function to remove the localStorage item when the user will click on the logout button.
When the localStorage item will remove, we will again change the isloggedin as false and navigate the user to the home page
2 3 4 5 6 7 8 |
onLogout() { localStorage.removeItem('Loginuser'); this.isloggedin = false; this.router.navigate(['/']); } |