How to Build and Implement JWT User Authentication in Angular 9 App

How to Build and Implement JWT User Authentication in Angular 9 App

In this Angular 9 JWT User Authentication tutorial, we are going to understand how to Build and Implement JWT User Authentication in Angular 9 Application. How to build a secure user authentication system using JSON web tokens (JWT) and RESTful Auth APIs built with Express, Node.js and mongoDB.

Welcome, fellas! Today, In this step-by-step Angular 8|9 tutorial, we are going to understand how to build a secure user authentication system using JSON web tokens (JWT) and RESTful Auth APIs built with express, node and mongoDB.

What is JWT (JSON Web Token)?

JWT refers to JSON Web token. It’s a token in string form validated and generated by a web server. This string-based token helps in communicating between the client and the server.

Let’s understand how does the JWT help in transferring the data securely between the client and the server.
User information is sent to the client like username and password using an HTTP POST request to the webserver. Web server identifies the user information and creates a token and send it back to the client. Client store that token into local storage or a session and also set it to the header. On the next HTTP call, that token is verified by the server, and web server returns the response to the client.

Angular 9 MEAN Stack User Authentication Work Flow
  • User can sign-in
  • User can register or sign-up
  • Store user data on MongoDB database.
  • Creating Angular service to handle user auth API.
  • Hide certain menu item based on authentication state
  • Restrict user to access user profile page when the user is not logged-in.
  • Store JWT token in local storage to manage the user session in Angular 8/9
  • Store password in mongoDB Database using the password hash method with bcryptjs.
  • Generate a JSON web token when a user logs in and store that token in a authorization header using HttpInterceptor class.

Table of contents

  1. Set up Angular 9 Project
  2. Clone Node Js Token-Based Auth REST API from GitHub
  3. Setting up HttpClient
  4. Creating User Authentication Service in Angular 9
  5. Set JWT Token with Angular 9 HttpInterceptor
  6. Protect Routes with CanActivate
  7. Implement Reactive Forms
  8. Implementing User Registration in MEAN Stack App
  9. Handling MEAN Stack Login with Angular 9
  10. Fetch User Profile in Angular 9 Auth App
  11. Conclusion
1. Set up Angular 9 Project

Let’s get started by installing the basic Angular app, enter the following command in your terminal:

ng new angular-meanstack-authentication

# ? Would you like to add Angular routing? Yes
# ? Which stylesheet format would you like to use? CSS

Next, head over to the Angular user authentication project folder:

cd angular-meanstack-authentication

To make things simpler create a separate front-end and backend (server) in Angular app. Our Angular 8/9 user auth app will have signin, signup and user-profile pages.

Create specific components folder in src/app/components in Angular app and create the following components in it.

ng g c components/signin

ng g c components/signup

ng g c components/user-profile

Next, install Bootstrap 4.

npm install bootstrap

Add the Bootstrap 4 stylesheet path in angular.json file.

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

Start your Angular app.

ng serve --open

2. Clone Node Js Token-Based Auth REST API from GitHub

Run the following command to clone Node.js token-based auth REST API from GitHub in your Angular’s root folder.

git clone https://github.com/SinghDigamber/node-token-based-authentication.git

Get inside the server folder:

cd node-token-based-authentication

Next, install npm packages to set up and start the Node server:

Run npm install to install required packages

Open other terminal run mongod

Next, install the nodemon NPM package for development purpose with --save-dev attribute, it helps in starting the node server when any change occurs in the server files.

npm install nodemon --save-dev

Open terminal run nodemon

Following auth APIs we are going to use in this tutorial.

Open API URL on http://localhost:4000/api

3. Setting up HttpClient

To handle REST APIs via HTTP requests in our Angular user authentication app. We need to import Angular HttpClient service in the auth module.

Import HttpClientModule service in app.module.ts file.

import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [
    HttpClientModule
   ]
})
4. Creating User Authentication Service in Angular 9

Now create Angular auth service and user class, these files will handle all the JWT user authentication related APIs in our project.

Inside the shared folder create shared/user.ts file and include the following code inside of it.

export class User {
    _id: String;
    name: String;
    email: String;
    password: String;
}

Next, run below command to create user auth service.

ng g s shared/auth

Add the following code in the shared/auth.service.ts file.

import { Injectable } from '@angular/core';
import { User } from './user';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})

export class AuthService {
  endpoint: string = 'http://localhost:4000/api';
  headers = new HttpHeaders().set('Content-Type', 'application/json');
  currentUser = {};

  constructor(
    private http: HttpClient,
    public router: Router
  ) {
  }

  // Sign-up
  signUp(user: User): Observable<any> {
    let api = `${this.endpoint}/register-user`;
    return this.http.post(api, user)
      .pipe(
        catchError(this.handleError)
      )
  }

  // Sign-in
  signIn(user: User) {
    return this.http.post<any>(`${this.endpoint}/signin`, user)
      .subscribe((res: any) => {
        localStorage.setItem('access_token', res.token)
        this.getUserProfile(res._id).subscribe((res) => {
          this.currentUser = res;
          this.router.navigate(['user-profile/' + res.msg._id]);
        })
      })
  }

  getToken() {
    return localStorage.getItem('access_token');
  }

  get isLoggedIn(): boolean {
    let authToken = localStorage.getItem('access_token');
    return (authToken !== null) ? true : false;
  }

  doLogout() {
    let removeToken = localStorage.removeItem('access_token');
    if (removeToken == null) {
      this.router.navigate(['log-in']);
    }
  }

  // User profile
  getUserProfile(id): Observable<any> {
    let api = `${this.endpoint}/user-profile/${id}`;
    return this.http.get(api, { headers: this.headers }).pipe(
      map((res: Response) => {
        return res || {}
      }),
      catchError(this.handleError)
    )
  }

  // Error 
  handleError(error: HttpErrorResponse) {
    let msg = '';
    if (error.error instanceof ErrorEvent) {
      // client-side error
      msg = error.error.message;
    } else {
      // server-side error
      msg = `Error Code: ${error.status}\nMessage: ${error.message}`;
    }
    return throwError(msg);
  }
}
  • The signUp() method stores the user name, email and password in mongoDB database.
  • By taking the help of bcryptjs, we are storing the password securely in the database.
  • The signin() method allows the user to access in the app using JSON web token generated by node server.
  • We are getting JWT token from the API response and storing in the local storage, then in the getToken() method, we are accessing the token via local storage getItem() method.
  • The isLoggedIn method returns true if the user is logged in else returns false.
5. Set JWT Token with Angular 9 HttpInterceptor

In this part of the tutorial, we are going to set the JSON web token in the header using Angular 8/9 HttpInterceptor. To set the authorization header, first create the authconfig.interceptor.ts file in the shared folder.

import { Injectable } from "@angular/core";
import { HttpInterceptor, HttpRequest, HttpHandler } from "@angular/common/http";
import { AuthService } from "./auth.service";

@Injectable()

export class AuthInterceptor implements HttpInterceptor {
    constructor(private authService: AuthService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler) {
        const authToken = this.authService.getToken();
        req = req.clone({
            setHeaders: {
                Authorization: "Bearer " + authToken
            }
        });
        return next.handle(req);
    }
}

Import the AuthService in and inject inside the constructor. In the intercept(){…} method call the getToken() method to get the JWT token then within the req.clone method set the Authorization header and call teh next.handle() method.

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './shared/authconfig.interceptor';

@NgModule({
  declarations: [...],
  imports: [HttpClientModule],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true
    }
  ],
  bootstrap: [...]
})

export class AppModule { }

Next, import the HTTP_INTERCEPTORS in the app.module.ts file and set the HTTP_INTERCEPTORS along with AuthInterceptor in providers:[...] array.

6. Protect Routes with CanActivate

Run following command to set up CanActivate interface class, It stops visitors to access certain urls in the Angular app. In our case we only want logged-in users to access the /user-profile URL.

ng g guard shared/auth

Next, add the following code in the auth.guard.ts file.

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, 
UrlTree, CanActivate, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './../shared/auth.service';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(
    public authService: AuthService,
    public router: Router
  ) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    if (this.authService.isLoggedIn !== true) {
      window.alert("Access not allowed!");
      this.router.navigate(['log-in'])
    }
    return true;
  }
}

Then, go to app-routing.module.ts file and import the AuthGuard interface class and inject the AuthGuard in the route as given below.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { SigninComponent } from './components/signin/signin.component';
import { SignupComponent } from './components/signup/signup.component';
import { UserProfileComponent } from './components/user-profile/user-profile.component';

import { AuthGuard } from "./shared/auth.guard";

const routes: Routes = [
  { path: '', redirectTo: '/log-in', pathMatch: 'full' },
  { path: 'log-in', component: SigninComponent },
  { path: 'sign-up', component: SignupComponent },
  { path: 'user-profile/:id', component: UserProfileComponent, canActivate: [AuthGuard] }
];

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

export class AppRoutingModule { }
7. Implement Angular 9 Reactive Forms

Import ReactiveFormsModule and FormsModule in app.module.ts file and also declare in imports: […] array.

import { ReactiveFormsModule, FormsModule } from '@angular/forms';

@NgModule({
  imports: [
    ReactiveFormsModule,
    FormsModule
  ],
})

export class AppModule { }
8. Implementing User Registration in MEAN Stack App

Now, implement user registration in MEAN stack auth app using Node API. Go to components/signup.component.ts file and add the following code.

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from "@angular/forms";
import { AuthService } from './../../shared/auth.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-signup',
  templateUrl: './signup.component.html',
  styleUrls: ['./signup.component.css']
})

export class SignupComponent implements OnInit {
  signupForm: FormGroup;

  constructor(
    public fb: FormBuilder,
    public authService: AuthService,
    public router: Router
  ) {
    this.signupForm = this.fb.group({
      name: [''],
      email: [''],
      mobile: [''],
      password: ['']
    })
  }

  ngOnInit() { }

  registerUser() {
    this.authService.signUp(this.signupForm.value).subscribe((res) => {
      if (res.result) {
        this.signupForm.reset()
        this.router.navigate(['log-in']);
      }
    })
  }
}

Go to components/signup.component.html file and add the following code inside of it.

<div class="auth-wrapper">
    <form class="form-signin" [formGroup]="signupForm" (ngSubmit)="registerUser()">
        <h3 class="h3 mb-3 font-weight-normal text-center">Please sign up</h3>
        <div class="form-group">
            <label>Name</label>
            <input type="text" class="form-control" formControlName="name" placeholder="Enter name" required>
        </div>
        <div class="form-group">
            <label>Email address</label>
            <input type="email" class="form-control" formControlName="email" placeholder="Enter email" required>
        </div>
        <div class="form-group">
            <label>Password</label>
            <input type="password" class="form-control" formControlName="password" placeholder="Password" required>
        </div>
        <button type="submit" class="btn btn-block btn-primary">Sign up</button>
    </form>
</div>

Call the signUp() method to register the user via the registerUser() method. On successful user registration redirect user to the log-in page.

9. Handling MEAN Stack Login with Angular

In this step, we will implement MEAN stack login in an Angular 8/9 app. Go to components/signin.component.ts file and add the following code.

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from "@angular/forms";
import { AuthService } from './../../shared/auth.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-signin',
  templateUrl: './signin.component.html',
  styleUrls: ['./signin.component.css']
})

export class SigninComponent implements OnInit {
  signinForm: FormGroup;

  constructor(
    public fb: FormBuilder,
    public authService: AuthService,
    public router: Router
  ) {
    this.signinForm = this.fb.group({
      email: [''],
      password: ['']
    })
  }

  ngOnInit() { }

  loginUser() {
    this.authService.signIn(this.signinForm.value)
  }
}

Head over to components/signin.component.html file and add the following code inside of it.

<div class="auth-wrapper">
    <form class="form-signin" [formGroup]="signinForm" (ngSubmit)="loginUser()">
        <h3 class="h3 mb-3 font-weight-normal text-center">Please sign in</h3>
        <div class="form-group">
            <label>Email</label>
            <input type="email" class="form-control" formControlName="email" placeholder="Enter email" required>
        </div>
        <div class="form-group">
            <label>Password</label>
            <input type="password" class="form-control" formControlName="password" placeholder="Password">
        </div>
        <button type="submit" class="btn btn-block btn-primary">Sign in</button>
    </form>
</div>

Enter the user email and password, we are setting up Authorization: Bearer token in the header when the user successfully logged-in.

10. Fetch User Profile in Angular 9 Auth App

Now, we will fetch the user data when the user is successfully logged in. In server/ /middlewares/auth.js file we have set the jwt.verify() method. This method checks the API request and does not render the user data if found invalid token or JWT secret.

For example try to access the /user-profile/_id Angular URL without providing the invalid token. You will find out that server doesn’t render the user data.

Get into the components/user-profile.component.ts file and include the following code inside of it.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AuthService } from './../../shared/auth.service';

@Component({
  selector: 'app-user-profile',
  templateUrl: './user-profile.component.html',
  styleUrls: ['./user-profile.component.css']
})

export class UserProfileComponent implements OnInit {
  currentUser: Object = {};

  constructor(
    public authService: AuthService,
    private actRoute: ActivatedRoute
  ) {
    let id = this.actRoute.snapshot.paramMap.get('id');
    this.authService.getUserProfile(id).subscribe(res => {
      this.currentUser = res.msg;
    })
  }

  ngOnInit() { }
}

Get into the components/user-profile.component.html file and include the following code inside of it.

<div class="container">
    <div class="row">
        <div class="inner-main">
            <h2 class="mb-4">User Profile</h2>
            <p><strong>Name:</strong> {{this.currentUser.name}}</p>
            <p><strong>Email:</strong> {{this.currentUser.email}}</p>
        </div>
    </div>
</div>

Adding Logout in MEAN App

In this step, we will add the logout, hiding and showing nav items in our MEAN stack user authentication app.

Go to app/app.component.ts file and add the following code inside of it.

import { Component } from '@angular/core';
import { AuthService } from './shared/auth.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

  constructor(public authService: AuthService) { }

  logout() {
    this.authService.doLogout()
  }
}

Go to app/app.component.html file and add the following code inside of it.

<div
  class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm fixed-top">
  <h5 class="my-0 mr-md-auto font-weight-normal">Angular Mean Auth</h5>
  <nav class="my-2 my-md-0 mr-md-3">
    <a *ngIf="this.authService.isLoggedIn" class="p-2 text-dark">User Profile</a>
    <a *ngIf="!this.authService.isLoggedIn" class="p-2 text-dark" routerLinkActive="active" routerLink="/log-in">Sign
      in</a>
  </nav>
  <a *ngIf="!this.authService.isLoggedIn" class="btn btn-outline-primary" routerLinkActive="active"
    routerLinkActive="active" routerLink="/sign-up">Sign up</a>
  <button (click)="logout()" *ngIf="this.authService.isLoggedIn" type="button" class="btn btn-danger">Logout</button>
</div>

<router-outlet></router-outlet>

11. Conclusion

Finally, we completed the Angular 8/9 JWT User Authentication Tutorial. In this tutorial, we have learned how to implement JWT user authentication in Angular 8/9 application.

Click below to get the full code of this tutorial on GitHub.

Git Repo

JSON Tutorial For Beginners | What is JSON | Learning JSON with JavaScript

JSON Tutorial For Beginners | What is JSON | Learning JSON with JavaScript

JSON Tutorial For Beginners | What is JSON | Learning JSON with JavaScript

Explore JSON and how JavaScript Objects can be used to access data within JSON data format and output to your web page

Guide to learning how to use JavaScript Objects and JSON data. JSON is the most popular format for data exchange between applications. If you are interested in connected to a web API chances are its JSON formatted. Learn to use AJAX to connect and bring JSON data into your JavaScript!

This course shows you how to work with JSON formatted data, output content, loop JSON data, Parse JSON and a whole lot more.

JSON (JavaScript Object Notation) is a syntax for data. JSON is easier to use than XML and human readable. Most modern web APIs output data in JSON formats. It's a lightweight data interchange format that is quickly becoming the default format for data exchange on internet today! JSON is lightweight, language independent and easy to read and write. JSON is better than XML and more popular!

Within the lessons of this course we will explore

  • JavaScript data types used to hold variables and how they work
  • JSON and how to write JSON data
  • How to add values into a JSON object
  • Accessing JSON data and bringing it into JavaScript
  • JavaScript JSON parse and stringify methods
  • Adding JSON to local storage
  • Retrieving back data within JSON formats, updating and working with JSON
  • Connecting to a web API using fetch
  • Retrieving JSON data from a web API and outputting the results into your web page
  • Iterating threw multiple results from an API
  • Google Spreadsheet data as JSON and how to practice retrieving data
  • All of the source code and resources are in included
  • Explore different methods of working with the JSON data stringify and parsing
  • How JavaScript objects can use Arrays to hold multiple items
  • How JavaScript arrays work and store data

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about JavaScript and JSON

The Complete JavaScript Course 2019: Build Real Projects!

JavaScript Programming Tutorial | Full JavaScript Course for Beginners 2019

The complete beginner’s guide to JSON

The Complete Guide to JSON Web Tokens

JWT Fundamentals for Beginners

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

New ES2019 Features Every JavaScript Developer Should Know

Javascript | How To Covert Javascript Array To JSON

Javascript | How To Covert Javascript Array To JSON

In this example, we will see How To Covert Javascript Array To JSON. We can convert Javascript array to json using JSON.stringify() method. At some point in your time, whatever developer you are, you need to deal with JSON data. JSON stands for Javascript Object Notation. Exchange data between client and server is straightforward using JSON.

In this example, we will see How To Covert Javascript Array To JSON. We can convert Javascript array to json using JSON.stringify() method. At some point in your time, whatever developer you are, you need to deal with JSON data. JSON stands for Javascript Object Notation. Exchange data between client and server is straightforward using JSON.

How To Covert Javascript Array To JSON

Javascript JSON.stringify() method converts Javascript array to json, and then we can send the string to the server.

Javascript JSON.stringify() is the inbuilt function in which it allows us to take the JavaScript Object or Array and create a JSON string out of it.

JSON.stringify() converts the value to JSON notation representing it:

If a value has the toJSON() method, it’s responsible for defining what data will be serialized.

See the following example.


// app.js

let data = [
  'krunal',
  'ankit',
  'rushabh'
]
jsonData = JSON.stringify(data)
console.log(jsonData)
console.log(typeof jsonData === 'string')

Output


➜  es git:(master) ✗ node app
["krunal","ankit","rushabh"]
true
➜  es git:(master) ✗

In the above code, we have defined a Javascript array with three values and then convert it into a JSON string using JSON.stringify() method.

Then we have printed JSON data in the console and check if the typeof jsondata is a string or not. Of course, it will return true because it is now JSON string ready to send the server via AJAX request. You can use the Axios library to send a network request.

JavaScript Object to JSON

We can use the same JSON.stringify() function to convert the Javascript object to json.

// app.js

let obj = {
  name: 'Krunal',
  rollno: 10,
  site: 'AppDividend'
}
jsonData = JSON.stringify(obj)
console.log(jsonData)
console.log(typeof jsonData === 'string')

Output

➜  es git:(master) ✗ node app
{"name":"Krunal","rollno":10,"site":"AppDividend"}
true
➜  es git:(master) ✗

We have defined an object and then pass to JSON.stringify() method, and it converts from Javascript object to json string.

Often, you need to convert the JavaScript values like string, array, or object into JSON before AJAX POST request.

The JSON object is now part of most modern web browsers (IE 8 & above).

Conclusion

We can convert Javascript datatypes like Number, Array, Object to JSON with just one function, and it is beneficial when exchanging data between client and server.

5 Secret features of JavaScript JSON.stringify()

5 Secret features of JavaScript JSON.stringify()

The JSON. stringify() method converts a JavaScript object or value to a JSON string. Let’s give it a try!

The JSON. stringify() method converts a JavaScript object or value to a JSON string.

Being a JavaScript developer, JSON.stringify() is the most common functions used for debugging. But what is the use of this, can’t we use our friend console.log() alone for the same? Let’s give it a try.

//Initialize a User object
const user = {
 “name” : “Prateek Singh”,
 “age” : 26
}

console.log(user);

RESULT
// [object Object]

Oops! console.log() didn’t help us print the desired result. It prints **[object Object]** because the default conversion from an object to string is “[object Object]”. So we use JSON.stringify() to first convert the object into a string and then print in the console, like this.

const user = {
 “name” : “Prateek Singh”,
 “age” : 26
}

console.log(JSON.stringify(user));

RESULT
// "{ "name" : "Prateek Singh", "age" : 26 }"

Generally, developers use this stringify function in a simple way as we did above. But I am gonna tell you some hidden secrets of this little gem which will make your life easy.

1: The second argument (Array)

Yes, ours stringify function can have a 2nd argument also. It’s an array of keys to the object which you want to print in the console. Look simple? Let’s take a closer look. We have an object product & we want to know the name of the product. When when we print it as:
console.log(JSON.stringify(product));
it gives the below result.

{“id”:”0001",”type”:”donut”,”name”:”Cake”,”ppu”:0.55,”batters”:{“batter”:[{“id”:”1001",”type”:”Regular”},{“id”:”1002",”type”:”Chocolate”},{“id”:”1003",”type”:”Blueberry”},{“id”:”1004",”type”:”Devil’s Food”}]},”topping”:[{“id”:”5001",”type”:”None”},{“id”:”5002",”type”:”Glazed”},{“id”:”5005",”type”:”Sugar”},{“id”:”5007",”type”:”Powdered Sugar”},{“id”:”5006",”type”:”Chocolate with Sprinkles”},{“id”:”5003",”type”:”Chocolate”},{“id”:”5004",”type”:”Maple”}]}

It is difficult to find the name key in the log as there is a lot of useless info displayed on the console. When the object grows bigger, difficulty increases.
The 2nd argument of stringify function comes into the rescue. Let’s rewrite the code again & see the result.

console.log(JSON.stringify(product,[‘name’]);

//RESULT
{"name" : "Cake"}

Problem solved, instead of printing the whole JSON object we can print only the required key by passing it as an array in the 2nd argument.

2: The second argument (Function)

We can also pass a 2nd argument as a function. It evaluates each key-value pair according to the logic written in the function. If you return undefined the key-value pair will not print. See this example for a better understanding.

const user = {
 “name” : “Prateek Singh”,
 “age” : 26
}


Passing function as 2nd argument

// Result
{ "age" : 26 }

Only age is printed as our function condition return undefined for the value typeOf String.

3: The third argument as Number

The third argument controls the spacing in the final string. If the argument is a number, each level in the stringification will be indented with this number of space characters.

Note: '--' represnts the spacing for understanding purpose

JSON.stringify(user, null, 2);
//{
//--"name": "Prateek Singh",
//--"age": 26,
//--"country": "India"
//}
4: The third argument as String

If the third argument is a string, it will be used instead of the space character as displayed above.

JSON.stringify(user, null,'**');
//{
//**"name": "Prateek Singh",
//**"age": 26,
//**"country": "India"
//}
Here * replace the space character.
5: The toJSON method

We have one method named toJSON which can be a part of any object as its property. JSON.stringify returns the result of this function and stringifies it instead of converting the whole object into the string. See this example.

const user = {
 firstName : "Prateek",
 lastName : "Singh",
 age : 26,
 toJSON() {
    return { 
      fullName: `${this.firstName} + ${this.lastName}`
    };
		
}

console.log(JSON.stringify(user));

RESULT
// "{ "fullName" : "Prateek Singh"}"

Here we can see instead of printing the whole object, it only prints the result of toJSON function.

I hope you learned some owsmm features of our little friend stringify(). If you find this article useful, please hit the ‘clap’ button and follow me with more exciting articles like this.