JavaScript Interview Series – All about NaN

nan1In JavaScript, NaN is one of the most confusing concepts; hence, it is often asked in the interview. You may have come across questions such as,

  • What is NaN
  • What is the type of NaN
  • How to check for the NaN
  • What is the difference between isNaN() and Number.isNaN()

In this post, let us learn the answer to the above questions one by one.

For me, The NaN is an error value in the JavaScript. However, technically it is the property of the global object. You get NaN when the value cannot be computed or as a result of attempted number coercion (type conversion) of non-numeric value (such that undefined) for which primitive numeric value is not available.NaN2

For example, for an arithmetic operation in which one of the operands is a missing value (read it undefined), JavaScript returns NaN. However, there are some other non-computational scenarios, such that divide by zero; instead of NaN you get Infinity value.



const foo = 7 + undefined; 
const too  = 7/0; 
console.log(foo); // NaN
console.log(too); // Infinity 


NaN3

You get value NaN in the following scenarios,

  • If one of the operands in an arithmetic operation is undefined
  • If one of the operands in an arithmetic operation is NaN
  • Dividing Zero by Zero
  • Dividing Infinity by Infinity
  • Multiplying zero with Infinity


let foo = 7 + undefined; // NaN
let koo = undefined - 7 ; // NaN 
let loo = NaN + NaN ; // NaN 
let hoo = NaN - NaN; // NaN 
let noo = 7 + NaN // NaN
let too = NaN * NaN // NaN
let poo = NaN % NaN // NaN
let roo = NaN % NaN // NaN
let zoo = 0 / 0 // NaN 
let qoo = 0 * Infinity; // NaN


NaN stands for Not a Number, and interestingly its type is number



console.log(typeof NaN); // number


NaN4

JavaScript treats NaN like any real number and can be used in any number type operations. The NaN is a property of the global object, and its other equivalent is Number.NaN.

NaN5

Keep in mind that both are the same.


console.log(NaN); // NaN
console.log(Number.NaN); // NaN 


The property attributes of NaN property are set to false. That means you cannot write, enumerate, or configure NaN property.



const NaNProp = Object.getOwnPropertyDescriptor(Number,'NaN');

/*Output 
{ value: NaN,
    writable: false,
    enumerable: false,
    configurable: false } */

console.log(NaNProp); 


Also, to use NaN property, you do not have to create the Number object, as it is a static property.

Check for NaN

In JavaScript, NaN is a value that is not strictly equal to itself, which makes it tricky to check for the NaN.

NaN8

It is not possible to rely on the equality operators (== and ===) to determine whether a value is NaN or not, because both NaN == NaN and NaN === NaN evaluate to false.



const foo = NaN; 
console.log(NaN === foo) // false 
console.log(NaN === NaN) // false 
console.log(NaN == foo) // false 
console.log(NaN == NaN) // false 


As you cannot use equality operator to check for the NaN value, JavaScript provides other ways to check value for NaN,

  1. isNaN() function
  2. isNaN()
  3. is(foo,NaN)

The Number.isNaN() method determines whether the value of the passed parameter is NaN and also its type is number.



const foo = NaN; 
console.log(Number.isNaN(foo)) // true 
const too = 'NaN';
console.log(Number.isNaN(too)) // false 


The Number.isNaN() method checks for both

  1. Whether the value is NaN
  2. Whether the type is number

As it checks for both types and the value, it always returns the expected result.


const foo = NaN;
console.log(Object.is(foo,NaN)); // true 
console.log(Object.is('NaN','NaN')); // true 
console.log(Object.is('NaN',foo)); // false


 

You can also use the Object.is() method to check for the value of NaN.



const foo = NaN;
console.log(Object.is(foo,NaN)); // true 
console.log(Object.is('NaN','NaN')); // true 
console.log(Object.is('NaN',foo)); // false


The Object.is() method determines whether two values are the same value or not. It checks for both equality and strict equality.  So you can also use the Object.is() method for the value of NaN.

How about isNaN()

The isNaN()  function also determines whether a value is NaN or not. Before checking for the value NaN, it tries to covert value to be tested as a number resulting in many unexpected results.



const foo = NaN;
console.log(isNaN(NaN)); // true 
console.log(isNaN(foo)); // true 
console.log(isNaN(undefined)); // true
console.log(isNaN(null)); // false 
console.log(isNaN(0/0)); // true
console.log(isNaN({})); // true
console.log(isNaN(false)); // false
console.log(isNaN(1234)); // false


In the above example, for many cases such that isNaN({}),  JavaScript is not able to do coercion of the passed value as a number, hence returns true.

Let us consider when you pass undefined in to check for the value of NaN in isNaN() function and JavaScript is not able to convert undefined to a valid real number; hence, it converts it to NaN, and as a result, you get true.

Starting ECMA 2O15, it is advisable to use Number.isNaN() method to check for the value of NaN.

NaN9

As a summary, JavaScript returns NaN for the value which can not be computed, and you should use Number.isNaN() to check whether a value is NaN or not.

I hope now you can answer about JavaScript NaN confidently in the interview.  Thanks for reading and any training or consulting need reach out to me at debugmode[at]outlook[dot]com 

Recognized as a Google Developer Expert by Google

I am officially a Google Developer Expert in Angular and Web Technologies. I take this opportunity to thank the Angular global community and all my students who come to my training, meetups, and workshops. This recognition was never possible without you.

a

I am humbled to be one of the few professionals who are awarded as both Microsoft MOST Valuable Professional and Google Developer Expert.

Though I have been awarded the Microsoft MVP Award 10 times since 2010, this is my 1st GDE recognition.

About GDE

As of the official website, GDE is a program to recognize individuals who are experts and help others. You can learn more about the program here

abc

There are around 110 Google Developer Experts in Angular all across the world, and I am humbled to be part of the esteemed group.  I understand this is a responsibility and would carry that with pride.

My Community Contributions

I have started working on Angular and JavaScript and for the Angular/ JavaScript community since August 2016, and since then

  • Organizing India’s Largest Angular Conference, ng-India. It’s third edition is happening on 29th Feb 2020 in Delhi. Find more details here
  • Have hosted 12 free full day Angular workshops in various Indian cities.
  • I have delivered 8 talks on Angular in various conferences. Find details here
  • I have written more than 50 blog posts on Angular. You can read them here
  • Authored best selling Angular book called Angular Essentials
  • Helped start-ups to embrace Angular as technology

Besides the above Angular contributions, I have also been making contributions to other technologies such as JavaScript, .NET, Azure, etc.

One of the most important aspects of the GDE program is mentoring others, and I have been mentoring many folks to be author, speaker, learn Angular to get a better job, etc, and I am very proud of that.  Below, sharing some photos from events I hosted in the past,

a1.jpg

a2

a3

a4

a5.jpg

The process to become GDE

There are four steps in the GDE process:

  1. The first step is the Nomination. The Country community lead, a member of the Google Product Team, or an existing GDE can nominate you for the GDE.
  2. The second step is the Community Interview. If your nomination is accepted, the next round is Community Interview, which is taken by an existing GDE in your expertise area.
  3. The third step is the Product Interview. Once you pass Community Interview, the third step is Product Interview, which is taken by a member of the product team.
  4. The fourth step is signing the NDA and getting accepted into the program.

Thank You

I was (perhaps am) always a Microsoft technologies boy. When I was just 25 years old, I received my 1st MVP award. Hence I have grown up with Microsoft technologies and is a Microsoft Most Valuable Professional who was always involved with MS stack. However, when I entered to open source community and started advocating JavaScript and Angular some individuals were very welcoming and supported me since beginning.  This post would be incomplete without thanking them.

Thank you, these amazing people, from the Angular community,

Todd Motto, Geard Sans, Deborah Kurata, Joe Eames, Jesse Sanders, Brian Holt, John Papa, and Ben Lesh

I also would like to thank my constant support for a decade now (in all my winters and summer)

Julie Lerman, Glenn Block, Dan Wahlin, Steve Smith, Stephen Forte, Rey Bango, and Jeff Fritz

From the Angular Team,

Stephen Fluin, Vikram, Jules Kremer, and   Brad Green

And last but not least thank you  to Shiv Prasad Koirala  ,  Gaurav Mantri, Abhishek Kant, and my elder brother Mritunjay Kumar

Once again, a big thank you to everyone who comes to my meetups, workshops, and ng-India. This was never possible without your love and respect.

What Next?

I will continue teaching and helping you understand when to use the async pipe and JavaScript prototype diagram. For any training or speaking reach out to me at debugmode@outlook.com

See you in India’s Largest Angular Conference , ng-India  on 29 February 2020.

Thanks

How to use Interceptor in Angular

Interceptors are used to intercepts HTTP requests and responses from the application. You can handle them or transform them before passing it on. For example, you can use an interceptor to add authorization token before passing the HTTP request or cache the HTTP response. Some of the usages of interceptors are as follows,

  • Caching of the response
  • Adding request headers such as authorization or any custom header for all outgoing requests.
  • Handling HTTP response error
  • Manipulating the URL
  • Faking the API
  • Authentication for every ongoing request etc.

To implement an interceptor, create a service that implements the HttpInterceptor interface.  The HttpInterceptor interface has one method intercept, which returns observable of HttpEvent and takes two inputs of types HttpRequest and HttpHandler.

abc

You can create an interceptor service as shown below,



import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable()
export class GlobalInterceptor implements HttpInterceptor{

    intercept(request :HttpRequest<any>,next:HttpHandler):Observable<HttpEvent<any>>{

        console.log(request.url);
        console.log(request.headers);
        console.log(request.body);
        return next.handle(request);
       // return null; 
    }
}


The above interceptor is simply printing request URL, headers, and body before passing the request object to the next method such that it can send it to the server.

After creating the interceptor service, you need to provide it to the application root module level.



@NgModule({
  declarations: [
    AppComponent,
    ProductsComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [{
    provide:ErrorHandler,useClass:GlobalErrorHandler},
   {provide:HTTP_INTERCEPTORS, useClass: GlobalInterceptor,multi:true}],
  bootstrap: [AppComponent]
})


 

Some important usage scenarios keep in mind that,

  • Import HttpClientModule only in the AppModule means root module
  • Add interceptors in the provide array of the AppModule
  • In case, if you import HttpClientModule in features module, then each module creates a copy of HttpClientModule, which overwrites the interceptor provided the AppModule.
  • You can provide more than one interceptor in the application. However, Angular apply them in the order they are provided.

Adding Headers

There are many usages of an interceptor, for example, if you want to set the header for every HTTP request, amend the request body, or set authorization header.  To set the header, first, clone the request object and set the header property.  You can also set the Content-Type and Accept header as shown below,



  // setting the header before sending the request
       const r = request.clone(
            {
            url:request.url.replace('http://','https://'),
            headers: request.headers.set('Content-Type', 'application/json')
            .set('Accept', 'application/json')
           }
        );

        return next.handle(r);


The above interceptor also replaces all request URLs from HTTP to HTTPS.  You can also set any new header means which are not standard HTTP header using the setHeader method,



 const r = request.clone(
            {
           // url:request.url.replace('http://','https://'),
            headers: request.headers.set('Content-Type', 'application/json')
            .set('Accept', 'application/json'),
            setHeaders:{'geek97':'ngIndia'}

           }
        );

        return next.handle(r);

 


Caching

The best way, you can use Interceptors request caching.  To cache requests, create an Angular service in which you register outgoing HTTP requests for caching.



import { Injectable } from "@angular/core";
import { HttpRequest, HttpResponse } from '@angular/common/http';

const maxAge = 20000;
@Injectable()
export class CacheRegistrationService {

    cache = new Map();
    get(req: HttpRequest<any>): HttpResponse<any> | undefined {
        const url = req.urlWithParams;
        const cached = this.cache.get(url);

        if (!cached) {
          return undefined;
        }

        const isExpired = cached.lastRead < (Date.now() - maxAge);
        const expired = isExpired ? 'expired ' : '';
        return cached.response;
      }

      put(req: HttpRequest<any>, response: HttpResponse<any>): void {
        const url = req.url;
        const entry = { url, response, lastRead: Date.now() };
        this.cache.set(url, entry);

        const expired = Date.now() - maxAge;
        this.cache.forEach(expiredEntry => {
          if (expiredEntry.lastRead < expired) {
            this.cache.delete(expiredEntry.url);
          }
        });
      }
}

 


 

You can have your own logic to register a request for the caching. However, I am just using a JavaScript Map() object to save outgoing requests for the caching.

I have written another post detailing about Maps in JavaScript here

Next, provide CacheRegisterationService at the AppModule level.



providers: [CacheRegistrationService, {
    provide: ErrorHandler, useClass: GlobalErrorHandler
  },
    { provide: HTTP_INTERCEPTORS, useClass: GlobalInterceptor, multi: true }],
  bootstrap: [AppComponent]


Now you can modify interceptor for caching as shown below,


@Injectable()
export class GlobalInterceptor implements HttpInterceptor {

  constructor(private cacheRegistrationService: CacheRegistrationService) {
    }
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

       const cachedResponse = this.cacheRegistrationService.get(request);
       return cachedResponse ? of(cachedResponse) : this.sendRequest(request, next, this.cacheRegistrationService);

      // return this.sendRequest(request,next,this.cacheRegistrationService);

    }
    sendRequest(
        request: HttpRequest<any>,
        next: HttpHandler,
        cache: CacheRegistrationService): Observable<HttpEvent<any>> {

    // cloning the request to modify the hedaer 
       const r = request.clone(
            {
                // url:request.url.replace('http://','https://'),
                headers: request.headers.set('Content-Type', 'application/json')
                    .set('Accept', 'application/json'),
                setHeaders: { 'geek97': 'ngIndia' }

            }
        );

        // Making the request and caching 

        return next.handle(r).pipe(
            tap(event => {
                if (event instanceof HttpResponse) {
                    cache.put(r, event);
                }
            })
        );
    }
}


We are just checking whether requests are cached or not before making request. In the network tab, you can check that only one request is made for multiple GET operations on the same API URL.

Handling HTTP error

You can also use interceptors for handling HTTP communication errors.  You can capture HTTP response error 401 and before that try request two times as shown below,


return next.handle(r).pipe(

            retry(2),
            catchError((error :HttpErrorResponse)=>{
                if(error.status ){
                    // log the eroor. pass it to global error handler
                    alert('error 401')
                }
                return throwError(error);
            })
        );


 

These are the few scenarios in which you can use the interceptor. I hope you like this post. For online or onsite Angular training reach me at debugmode@outlook.com .

When to use the subscribe method or async pipe in Angular?

Let us start with depicting the usage of both ways of data retrieval with a high-level diagram:

dhananjay kumar

Commonly, we work with observable data in a component class. One such classic example is CRUD operations on a REST API. For this, mostly we use Angular’s HttpClient class’s methods to perform various HTTP request operations, which returns HTTP responses as an observable.

This blog post discusses various ways of reading observable data in a component and their characteristics. Predominately there are two ways to read observable data,

  1. Using the async pipe
  2. By subscribing to the observable using the subscribe() method

We will discuss both these options and their behavior corresponding to a particular change detection strategy.  To refresh, Angular has two Change Detection strategies

  1. default
  2. onPush

In the onPush strategy, Change Detection runs when a new reference is being passed to the component.

Fetching data from the API

Let us say we have an API that returns Product data as JSON, and we have a requirement to display the returned data in a component.  For understanding, the Product data looks like below,

pic 2

To work with the API data, first, we create an entity class as shown next, where each properties crosspond to the columns of data returned,



export class Product{

        public  ProductID : string;
        public  Title : string;
        public Price : number ;
        public Color : string;
        public inStock: string;
        public  Details: string;
        public Quantity: number;
        public Rating: number;
        public  ExpiryDate: string;
        public  ImageUrl: string;
    }


And after that, we create an Angular Service and inside service initially do the following tasks,

  • Inject HttpClient service
  • Configure HTTP header
  • Configure HTTP request options

These tasks can be done using the code listed below,



export class ProductService {

  // API URL
  apiurl = "https://localhost:44316/api/products";

  // Setting request headers to JSON
  headers = new HttpHeaders()
            .set('Content-Type', 'application/json')
            .set('Accept', 'application/json');

  httpOptions = {
    headers: this.headers
  };
  constructor(private http: HttpClient) { }

  // rest of the code ...
}


So far, we have created an HTTP Request Header and injected HttpClient Service. Next, to fetch data from the API, we perform HTTP GET operation.

The HttpClient service has a various method to perform various HTTP operations, among them, get method performs HTTP GET operation. We can use get method as shown next,



  getProducts(): Observable<Product[]> {
    return this.http.get<Product[]>(this.apiurl, this.httpOptions)
    .pipe(
      tap(data => {
        // debug here
        console.log(data);
      }),
      catchError(this.handleError)
    );
  }


The getProducts() function either returns an observable of product array or returns throwError observable.

The HttpClient service’s get method returns HttpResponse as observable with the response body is set to the request type. This means it does content negotiation with the API, and if Content-Type is set to JSON, it returns a response as JSON.

We have also used RxJS operators,

  • tap : to tap in the input stream and log the returned data
  • catchError : to handle the error in the HTTP request and throw an error as observable

The handeError function returns a creational function throwError, which creates a stream of the error.



 private handleError(error: any) {
    return throwError(error);
  }


So far, Angular services have a function in which we are making HTTP Request to the API and return HTTP response.  Putting everything together service will look like next code listing,



import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Product } from './product.enitity';
import { Observable, throwError } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  // API URL
  apiurl = "https://localhost:44316/api/products";

  // Setting request headers to JSON
  headers = new HttpHeaders()
            .set('Content-Type', 'application/json')
            .set('Accept', 'application/json');

  httpOptions = {
    headers: this.headers
  };
  constructor(private http: HttpClient) { }

  getProducts(): Observable {
    return this.http.get(this.apiurl, this.httpOptions)
    .pipe(
      tap(data => {
        // debug error here
        console.log(data);
      }),
      catchError(this.handleError)
    );
  }

  private handleError(error: any) {
    return throwError(error);
  }

}


 

Using the subscribe() method

Everything good so far.  Now in the component class, to use ProductService first, you inject it and create variables to stored returned data



export class ProductsComponent implements OnInit, OnDestroy {

  products: Product[] ;
  productsubscription: Subscription;
  constructor(private productservice: ProductService) { }


The products variable will store returned data from the service, and productsubscription variable will store the observable.   Data can be read from the ProductService as shown in the next code listing.



getProducts() {
    this.productsubscription = this.productservice.getProducts().subscribe(
      (data) => {this.products = data;},
      (error) => { console.log(error) },
      () => { console.log(`products stream completed`); }
    );
  }


We are simply subscribing to the getProducts() method of the service and reading the returned data  in the products variable. We have also handled the error and complete functions by logging respective information.

Putting everything together the component class which subscribes to the HTTP response using a service looks like next code listing,



@Component({
  selector: 'app-products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.css'],
  changeDetection:ChangeDetectionStrategy.Default
})
export class ProductsComponent implements OnInit, OnDestroy {

  products: Product[] ;
  productsubscription: Subscription;
  constructor(private productservice: ProductService) { }
  ngOnInit() {

    this.getProducts();
  }

  getProducts() {
    this.productsubscription = this.productservice.getProducts().subscribe(
      (data) => {this.products = data;},
      (error) => { console.log(error) },
      () => { console.log(`products stream completed`); }
    );
  }
  ngOnDestroy() {
    this.productsubscription.unsubscribe();
  }
}


A couple of important points worth discussing the ProductsComponent class are,

  • The Change Detection Strategy of the component is set to default
  • The component is explicitly unsubscribing to the observable in the ngOnDestroy() life cycle hook.
  • If the component subscribes to many observables, then we have to manually unsubscribe them, and not doing so may cause memory leaks and may have a performance impact

Keeping the above point in mind, implementation in the ProductComponent using the subscribe method does its task perfectly to read observable data from the service. On the template, data is displayed as shown next:




<h2>Product Loading .....</h2>

<div>
<table>
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Price</th>
<th>Color</th>
<th>Quanity</th>
<th>Rating</th>
<th>In Stock</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{p.ProductID}}</td>
<td>{{p.Title}}</td>
<td>{{p.Price}}</td>
<td>{{p.Color}}</td>
<td>{{p.Quantity}}</td>
<td>{{p.Rating}}</td>
<td>{{p.inStock}}</td>
</tr>
</tbody>
</table>
</div>

 

Everything is fine in the above implementation, and you should get data displayed in the table.

p3

So far, so good. Now go ahead and set component’s change detection strategy to onPush.

p4

Now you find that data is not displayed in the table, and instead of that you are getting Product Loading message.

p6

 

Since getProducts() does not return new reference and change detector is set to onPush, Angular does not run the change detector.  You can solve this by manually instructing Angular to run a change detector.  To do that,

  1. Inject ChangeDetectorRef service in the component
  2. Use markForCheck in the subscription method to instruct Angular to check the component by running the change detector.

p7

Now you will find data is rendered in the table again.   Above we are manually marking the component for the change and also manually unsubscribe when components get destroyed.

Advantages of subscribe() approach are,

  • Property can be used at the multiple places in the template
  • Property can be used at the multiple places in the component class
  • You can run custom business logic at the time of subscribing to the observable.

Some of the disadvantages are,

  • For the onPush change detection strategy, you have to explicitly mark component to run the change detector.
  • Explicitly unsubscribe the observables.

This approach may go out of hand when there are many observables used in the component. If we miss unsubscribing any observable, it may have potential memory leaks, etc. Nevertheless, putting everything together,



import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { ProductService } from '../product.service';
import { Product } from '../product.enitity';
import { Observable, Subscription } from 'rxjs';

@Component({
  selector: 'app-products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.css'],
  changeDetection:ChangeDetectionStrategy.OnPush
})
export class ProductsComponent implements OnInit, OnDestroy {
  products: Product[] ;
  productsubscription: Subscription;

  constructor(private productservice: ProductService,
               private cd: ChangeDetectorRef) { }

  getProducts() {
    this.productsubscription = this.productservice.getProducts().subscribe(
      (data) => {
        this.products = data;
        this.cd.markForCheck();
      },
      (error) => { console.log(error) },
      () => { console.log(`products stream completed`); }
    );
  }

  ngOnInit() {

    this.getProducts();
  }

  ngOnDestroy() {
    this.productsubscription.unsubscribe();
  }
}


 

Async pipe

The second or some people consider it a better approach is to work with observable data is by using async pipe.  To use async pipe,

  1. Declare a variable of observable type
  2. Call the service method which returns observable

First, declare a variable like below,



products$ : Observable;


and then make a call to the service,



  getProducts() {
     this.products$ = this.productservice.getProducts();
    }


And on the template, use an async pipe to display the observable data, as shown next




<h2>Product Loading .....</h2>

<div>
<table>
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Price</th>
<th>Color</th>
<th>Quanity</th>
<th>Rating</th>
<th>In Stock</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{p.ProductID}}</td>
<td>{{p.Title}}</td>
<td>{{p.Price}}</td>
<td>{{p.Color}}</td>
<td>{{p.Quantity}}</td>
<td>{{p.Rating}}</td>
<td>{{p.inStock}}</td>
</tr>
</tbody>
</table>
</div>

We used async pipe in *ngFor directive to display the observable data. Main advantages of using the async pipe are

  1. In onPush change detection strategy, if observable data changes it automatically marks component for the check.
  2. On component destruction, it automatically unsubscribes the observable hence avoids chances of any potential memory leak

Using the async pipe keeps code cleaner, and also you don’t need to manually run change detector for onPush Change Detection strategy.  To use async pipe component class will look like below,



import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { ProductService } from '../product.service';
import { Product } from '../product.enitity';
import { Observable, Subscription } from 'rxjs';

@Component({
  selector: 'app-products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.css'],
  changeDetection:ChangeDetectionStrategy.OnPush
})
export class ProductsComponent implements OnInit {

  products$ : Observable;

  constructor(private productservice: ProductService) { }

  getProducts() {
     this.products$ = this.productservice.getProducts();
    }

  ngOnInit() {

    this.getProducts();
  }

}


Now, I hope you have a better understanding of when to use subscribe method approach and when to use async pipe.  So, to summarize let us revisit the diagram we shared in the beginning of this post,

dhananjay kumar

My suggestion is when in doubt use async pipe 😊. I hope you find this post useful. Thanks for reading.

 

I am an indepnedent Trainer and Consultant on Angular, JavaScript, Node, .NET Core, REST , GraphQL . To hire reach me at debugmode@outllook[dot]com or tweet me  @debug_mode

 

 

 

 

 

 

 

Delivering two talks at Devfest Gandhinagar 2019

Ahmadabad is always very close to me as I did my first public speaking in this city back on 24 July 2010.  Since then I have been trying to do at least one workshop or talk each year here, so continuing the ritual, I am again coming to Ahmadabad/Gandhinagar on 13th October to speak in   Devfest Gandhinagar 2019

You can follow all happening of the conference here or follow them on twitter here

a

I am excited to deliver two talks. They are as follows:

Talk 1: JavaScript Interview Questions Made Simpler

Usually they ask these questions in a JavaScript interview.

  1. What is the value of ‘this’?
  2. What are the invocation patterns?
  3. Various ways to pass parameters to a function?
  4. Explain Hoisting?
  5. How to make objects properties read only?
  6. How to make objects properties private?
  7. Explain constructor and prototype
  8. What is __proto__
  9. How will you create inheritance in JavaScript?
  10. ES2015
    1. Arrow functions
    2. REST parameters
    3. Spread operator
    4. Default parameters etc.

I will try to simplify 5-7 topics from the above listed topic in a simpler and entertaining way.  This talk is for everyone and your main take away from this session would be at least that you will never forget what is value of ‘this’ 😉

Talk 2:  Simplifying RxJS in Angular for everyone

We all use subscribe() method in an Angular application to fetch data from the API. However, very rarely know beyond that, I will try to take you beyond obvious.  In this talk, I will start from the beginning of RxJS in Angular and then end at the best practices of using it.

  1. Using of, from creational functions
  2. Sharing data between two unrelated components
  3. Fetching data from the API
  4. Using async pipe
  5. Using other operators such as a map, forkJoin etc.

This talk is for the developers who are already working on the Angular.

I am excited to see you in both of my talks.  When you see me in the event, do not hesitate to say Hi and take a selfie together.

I wish to thank Yatendrasinh Joddha, Parth Jansari, Arif Khoja  , Bhavesh Valand, and the whole team of GDG Gandhinagar for inviting me. I hope to meet the expectation of audiences and teach them a few things.

Simplifying Maps in the JavaScript

t3

Maps is a data structure, which stores the key/value pair in an ordered way.  Since the inception of the JavaScript, objects are primarily used for the map.  Consider the below code listing:



var foo = {
    id:1,
    color : 'Red'
}

console.log(foo['id']); // 1 
console.log(foo.color); // Red

 


To store two key/value pairs, we have created an object foo and using the keys such as id and color to retrieve the values. It is straightforward, however using an object for the map has two major challenges,

  1. It is unordered, means it does not remember the original insertion order of the keys
  2. The only string can be used as the key

There is a challenge in using only string as the key. Let us consider the code listed below,



var z = {};

var x  = { id : 1};
    y  = { id : 1};

z[x]= 'foo';
z[y] = 'bar';

console.log(z[x]); // bar 
console.log(z[y]); // bar


Surprisingly bar is printed twice because,

  1. Objects can have an only string as the key
  2. Since x and y both are an object JavaScript is converting them to string  value ‘[object, Object]’
  3. For the z object, there is only one key ‘[object, object]’ is set

You can verify that there is only one key is set for the object z as shown below,



console.log(Object.keys(z)); // [ '[object Object]' ]


These are the problems in using an object as a map. You can solve it by using the Map object introduced in ES6.



var z = new Map();

var x  = { id : 1};
    y  = { id : 1};

z.set(x,"foo");
z.set(y,"bar");
console.log(z.get(x)); // foo 
console.log(z.get(y)); // bar


Instead of using square brackets, you use set() for write and get() for reading operations in the Map. The other essentials methods with Map objects are

  1. The delete(key) method – to delete a key
  2. The size() method – return the total number of keys
  3. The clear() method – delete all keys from the Map

These methods can be used as shown in the code listing below,



console.log(z.size); // 2
z.delete(x); // returns true
console.log(z.size); // 1
z.clear(); 
console.log(z.get(y)); // undefined
console.log(z.size); // 0


One important thing is delete method of the Map object is different from the delete operator, which is used to delete the object’s properties.

Reading values from the Map

You can read values from the Map using the values() method. It returns an iterator object that contains values for all the keys. It returns values in the order they were added to the Map.  You can use values() method as shown below,



var z = new Map();

var x  = { id : 1};
    y  = { id : 1};

z.set(x,"foo");
z.set(y,"bar");
z.set('range', 30);
let zvalues = z.values();
console.log(zvalues);


 

The values method return an iterator as shown in the below image,

t1

You can convert an iterator to an array using the spread operator or Array.from as shown in the below code listing:



let zvalues = z.values();
let zvaluesarray = [...zvalues];
let zvaluesarray1 = Array.from(z.values());
console.log(zvaluesarray); // ['foo','bar',30]
console.log(zvaluesarray1); // ['foo','bar',30]

 


 

Reading keys from the Map

You can read the keys from the map using the keys() method.



let zkeys = z.keys();
let zkeyaarray = [...zkeys];
console.log(zkeyaarray); 


 

You get an output as shown in the below image. Like values(,) method, the keys() method also returns an iterable, and you can use the spread operator to convert it to an array.

t2

You can use has() method to check whether a particular key exists or not, it returns true if the key exists otherwise false.



var z = new Map();
var x  = { id : 1};
    y  = { id : 1};

z.set(x,"foo");
z.set('range', 30);

console.log(z.has(x)); // true 
console.log(z.has(y)); // false 

 


 

The has() method returns false for y as it is not part of the map z.

Initializing Map with the Arrays

The Map constructor can optionally take an iterable object or an array as the parameter. You can pass an array as the parameter to the Map constructor as shown below,



const fooarray = [
    ['1', 'One'],
    ['2', 'Two'],
    ['3', 'Three'],
  ];

var z = new Map(fooarray);
console.log(z.get('1')); // 1
let zvalues = z.values();
let zvaluesarray = [...zvalues];
console.log(zvaluesarray); // [ 'One', 'Two', 'Three' ]


 

The Object and the Map

As we saw that objects could be used to work with key/value pair, however, there are substantial differences between using the object and the Map,

  • You can use functions and objects besides other primitive types as the key in the Map, whereas for the Object only string or Symbols can be used.
  • The keys in the Map are ordered, whereas Keys in the Object are unordered.
  • You can use the size method to find the size of the Map, whereas to find several properties in the Object, you have to do manually
  • A Map is iterable, whereas an Object is not, you need to fetch the keys and then iterate over them manually
  • Each Object has a prototype and its default properties, so you need to make sure that map keys name does not collide with the properties name from the prototype.

 

One more important factor is frequent read and write operations on a Map could be faster than of an Object.

WeakMaps

If you use an object as a key in a Map, and all the references of the object are removed, still object is not eligible for the Garbage Collection until its entry is not deleted from the Map itself.  Therefore, if a Map uses an object as a key, you will have to remove it from the Map to make it eligible for the Garbage Collection.  The other solution is to use the WeakMap; they are better suitable for the Garbage Collection.

In the context of Garbage Collection, Some of the characteristics of the WeakMaps are,

  1. It takes only objects as the key
  2. Objects are held weakly in the map
  3. If the reference of the object is removed, it is available for the GC and will also be deleted from the map
  4. If the object is garbage collected, the WeakMap will have no reference for it.

 

You can use a WeakMap almost in the same way as a Map. However, keep in mind that all the methods of the Map are not available with the WeakMap.  A WeakMap can be created, as shown below:



var z = new WeakMap();
var x  = { id : 1};
    y  = { id : 1};
    m  = { id:1 };

z.set(x,"foo");
z.set(y,'bar');

console.log(z.has(x)); // true 
console.log(z.has(y)); // true  
console.log(z.has(m)); // false 

 


Keep in mind that the WeakMap does not have methods such as:

  • values()
  • size()
  • clear()
  • keys()
  • entries()

If you perform these operations on the WeakMap, JavaScript will throw an error.

Summary

As you learned in this post that the Map object makes it simpler to work with a key/value pair in JavaScript. It has a rich API and should be used over an object.  I hope you like this post. Thanks for reading.

For any training or consulting need to reach me at debugmode@outlook.com or follow me on twitter @debug_mode, or if you prefer to let us connect on LinkedIn

Announced- geek97 step by step Angular Bootcamp on 5-6 October in Gurgaon

To attend register here: https://forms.gle/JSbp3yknZ7scr9BP7

Many of you asked me to host a Bootcamp in Delhi/NCR. I got motivated by your constant request, hence decided to give a try. For geek97, I am hosting the next Bootcamp in Gurgaon on 5-6 October.

Details

b1

To attend register here: https://forms.gle/JSbp3yknZ7scr9BP7  and for any clarification send me a mail at debugmode[at]outlook.com

Agenda of the training is as below,

Lecture 1: Getting started and Data Binding – 1.5 Hrs

  • Interpolation
  • Event Binding
  • Property Binding
  • Two-way data binding
  • Using directives such as *ngFor, *ngIf
  • Using inbuilt type
  • Creating a custom search pipe

Lab – Displaying Data in a table from local JSON array using *ngFor

Lecture 2: Component Communications – 2 Hrs

  • @Input
  • @Output and EventEmitter
  • Temp Ref Variable
  • Understanding Life Cycle Hook when the component has @Input decorated properties
  • Introducing Change Detector

Lab:  Master – Details Application using component communication

Lecture 3:  Services and Providers – 1.5 Hrs

  • Creating first service
  • Understanding Dependency Injection
  • Using @useclass, @useexisting, @usevalue, @usefactory
  • Understanding injector tokens
  • Share data between two unrelated components

Lab:  creating global variable and inject to whole application

Lecture 4:   Custom Attribute Binding – 0.5 Hrs

  • Custom Binding
  • @HostBinding
  • @HostListener

Lecture 5:  Reactive Forms – 1.5 Hrs

  • Template Forms and Reactive Forms
  • Creating Reactive Forms
    • FormControl
    • FormGroup
    • FormBuilder
    • FormArray
  • Custom Validators
  • Conditional Validators
  • setValue and patchValue

Lecture 6:   Introducing RxJS – 2.5 Hrs

  • What is reactive way of thinking
  • Observables and subscribe
  • RxJS operators
    • Tap
    • Map
    • Take
  • Different types of subjects
  • Fetching data using observable – subscribe
  • Async pipe
  • Handling errors
  • Declarative Pattern of Data Retrieval

Lecture 7:  Change Detection – 1 Hrs

  • Different strategy
  • How to optimize CD for better performance

Lecture 8:  Routing basics and Lazy Loading – 1.5 Hrs

  • Adding Routing modules
  • Adding feature modules
  • Lazy loading modules
  • Passing value from one route to another route
  • Route Guards

Final Project – Creating End to End CRUD operation using REST API – 3 Hrs

  • Creating Main Modules and Feature Modules
  • Adding service to perform
    • Create
    • Update
    • Read
    • Delete
    • Handling Error
  • Using service in various components
    • Add product
    • Delete Product
    • Product Details
    • Update Product
  • Adding authentication
  • Discussing how we can make this application architecture better

Closure – 1 Hrs

  • Discussion and doubts
  • Angular 8 features
  • Deciding the learning path

At the end, everyone will get a geek97 certificate.

b2

If required we can help you finding better opportunities also on basis of this training. We keep getting requirements, and on your approval, we will recommend you.

To attend register here: https://forms.gle/JSbp3yknZ7scr9BP7  and for any clarification send me a mail at debugmode[at]outlook.com

If you can not afford 4000 INR and really need training contact me at 9717098666 . I will see, how can I help.

Hosted Angular Bootcamp in Jabalpur for Taritas software

Angular is becoming more popular with each passing day in India. Companies of different sizes are using it to deliver the project for their customers.  One such company Taritas  . They have offices at multiple locations and with clients all across the world.

They invited me on 21-22 September to host a 16 hrs long Bootcamp for their engineers on Angular.

In the Bootcamp, we covered the following topics

  • Data Binding
  • Component Communications
  • Custom Attribute Directives
  • Pipe and async pipe
  • Reactive Forms
  • Change Detection
  • Services and Providers
  • Sharing data using subjects
  • Data-driven strategies and async pipe
  • Lazy loading
  • Best practices

The engineers of Taritas were very motivated after becoming geek97 certified Angular Developer.

Some of the testimonials from the attendees was,

“It was our pleasure to attend the training on Angular by super talented DJ this session was very interactive and easy to understand …. We had an amazing experience
Thank you so much for sharing your knowledge with us 😊”

~Prati Tembhre

 

“Got a chance to attend DJs 16 hours training program on Angular 8 and that was a very informative session. Everything was explained in such an interesting way that the topics or concepts seemed to be simple and easy to catch. Would love to be a part of such sessions again 😊”

~ Meenal Tiwari

“A Big Thanks to DJ Sir For inspiring us to learn Angular and JavaScript.
His workshop was filled with knowledge and Positivity.
Thanks a lot for training us.”

~Shubham Pawaiya

 

After 16 hrs, we had open discussions and certificate distributions.

Also, they are hiring more Angular developers. To know more about the opportunity reach out to me. I thank Supreet, Neha, Atul, Varun, Shilpi, and the whole team for this opportunity and hospitality.

To hose similar workshops for your team reach me at debugmode[at]outlook.com

 

 

Why you need Proxy objects in JavaScript

JavaScript is not truly Object Oriented language, hence implementing requirements as stated below could be challenging. For example,

  • Throw an error if the setting value of a property does not satisfy a particular condition
  • If the property does not exist on set some default value instead of undefined
  • If the property does not exist on reading operation throw TypeError
  • Create a private property on the object
  • Enforce property value validation
  • Enforcing value correct on the property

There are many ways some of the above stated problems can be solved, such that by using setter or getter to set default value or throwing an error or using an object’s methods such that isExtensible(), preventExtension(, etc to avoid adding dynamic properties etc. However, the more convenient way to handle the above problems is by using the Proxy object.

You can watch video on the proxy object here:

The Proxy object is a virtualizing interface to control the behavior of the object.  To understand the proxy in a better way, let us consider Product object as shown in below code listing:


let Product = {
    id:1,
    price : 78
  }

 

The Product object has two properties id and price. Now let us say that you want to run a business logic that price should not be less than 50, or reading value of the property, which does not exist, should throw error, etc.

You can solve most of the above problems by running custom logic while performing property lookup, set, get, and enumeration operations on the object. JavaScript proxy object exactly helps here. It allows you to add custom behavior to the fundamental operations on a JavaScript object.

po

 

The syntax to create a Proxy object is as shown in the below image:

po1

You create a proxy object using the Proxy constructor and passing two parameters in it.

  1. Target
  2. Handler

Target is the object, which proxy virtualizes and adds custom behavior to it. In our example, the Product object is the target as we are adding custom behavior to it.

The handler is the object, in which you write the custom behavior. In more technical words, the handler object contains the trap.

The traps are the methods, which gives the target object’s property access inside the handler object. Traps are optional, and if not provided target object’s default methods are used.   There are traps such as to get, set, has, setPrototypeOf, isExtensible, defineProperty, etc. You can use all of these traps in the handler do define custom behavior for the target object.

Let us apply a custom behavior on the Product object that, a read operation on the property that does not exist should throw an error.  You can create a proxy for that as shown in the below code listing :


var ProductHandler = {
      get:function(obj,prop){
          return prop in obj ?
          obj[prop] : new TypeError(prop + ' - property does not exist');
      }
  };

var productProxy = new Proxy(Product,ProductHandler);

 

Let us walk through the code; we created a proxy called productProxy using the Proxy constructor and in the Proxy constructor passing,

  1. The Product object as the target
  2. The ProductHanlder object as the handler.

The ProductHandler is using the get trap, in which it is checking if property exists in the object or not. If it does not exist, return a TypeError with the message.  Now read properties value as shown in code listed below:


console.log(productProxy.price);
console.log(productProxy.color); 

 

Since price property exists, you get 78 value printed, however when you try to read property color, which does not exist, JavaScript throws you an error as shown in the image below:

po3.png

The better use case of proxy is in validation. Using the proxy, a validation can be enforced on the property value.  Let us consider the code listed below,


let Product = {
    id:1,
    price : 78
  }

Product.price = -10; 
console.log(Product.price); // -10

We can set prices to a negative value. Using the proxy, we can avoid it by enforcing value validations, as shown in the code listed below:


var ProductHandler = {
    set : function(obj, prop,value){
        if(prop == 'price'){
            if( !Number.isInteger(value)){
                throw new TypeError('passed value is not a number');
            }
            if(value < 50){
                obj[prop]= 50;
                return true; 
            }
        }
        obj[prop]= value;
        return true; 
    }
};

var productProxy = new Proxy(Product,ProductHandler);

 

To enforce value validation handler object is using the set trap, in which it is

  1. Checking for the property price
  2. Verifying whether the passed value is an integer or not
  3. If the passed value is for property price is less than 50, setting the value to 50

Now when you set price to a negative value due to defined custom behavior in the proxy object JavaScript will not allow that, and you will get 50 printed for second read operation as shown in code listed below,


console.log(productProxy.price); // 78
productProxy.price = -10; 
console.log(productProxy.price); // 50

 

You can enforce id as the private property of the Product object as shown in the code listed below:


var ProductHandler = {
    get:function(obj,prop){

        if(prop == 'id'){
            throw new Error('Cannot access private property : id!');
        }
        else {
            return prop in obj ?
            obj[prop] : new TypeError (prop + ' - property does not exist');
        }
    }
};

var productProxy = new Proxy(Product,ProductHandler);

 

Here, in the get trap of the handler, we check if the property being accessed is the id property, and if so, handler throws an error. Otherwise, it returns the value as usual.

JavaScript Proxy objects are useful and allow us to add custom behavior to a normal object.  You can use it for various purposes such as validation, creating access modifier, setting default values, etc.  I hope you find this post useful. Thanks for reading.

For any Training or Consulting reach me at debugmode[at]outlook.com 

Step by Step implementing Two-Way Data Binding in Vanilla JavaScript

Data Binding is one of the most important features of all the frameworks. It ensures that the data model and the views are in sync with each other. It is very fundamental feature of any MV* frameworks such that Model-View-Controller, Mode-View-ViewModel, and Model-View-Presenter, etc.

Popular JavaScript based frameworks such that React, Angular have their way to implement it. However, it is a good idea to know how a basic two-way data binding can be implemented using vanilla JavaScript.  That would give you an overview of how much heavy lifting is done by the framework when you use features like data binding.

To get most of this post, you should have a basic understanding of following JavaScript features

  • Creating an object as literal
  • Adding a property with Object.defineProperty
  • Using setter and getter
  • forEach statement

 

You can refresh about JavaScript object creation in this video on geek97. Let us get started,

On the HTML, we have put one input text box and two span elements.  Whenever the user enters a value in the text box, data in <span> element should get updated.

We are going to write JavaScript for data binding in the databinding.js file, so we also added a reference to that in the HTML.

To start with databinding.js file contains an Immediately Invoked Function Expression (IIFE). We write all the codes inside this function,

At this point, on launching the application, you should get below output. Right now, if you enter anything in the Name field nothing would be affected.

cd1

Note: If you are using Visual Studio Code, install the extension Live Server, and run the HTML in the browser, right click on the file and from the context menu select “Open with Live Server” to launch the application.

Our first task is to select all the elements which have [data-geek97-bind] attribute set, and also check for their type. Right now, as we are creating binding only for input type text, so we can make a selection of elements and type checking as shown below,

We have created an empty object called dbrepo, which would maintain the state between the data bound elements. The dbrepo object would make sure that all DOM elements with [data-geek97-bind] attribute set to value ‘name’ is in sync and have the same value.

To achieve that, what all we need to do is to add a property dynamically to the dbrepo object for each unique value of [data-geek97-bind] attribute in the DOM elements. For that, let us create a function called addToScope. In the function, we check whether a particular property exists or not, if not then using the Object.defineProperty() method adds a property to the dbrepo object.

Using the hasOwnProperty() method, determining whether property already exists or not, if not then add it using the Object.defineProperty() method. You can learn more about property descriptor and Object.defineProperty() here

We need to do some work in the setter function.

  • First, find all the elements with data-geek97-bind attribute set to the same value.
  • If the element type is text, set its value, otherwise set innerHtml of the element

Above two tasks can be performed in the setter function as below,

Putting everything together, code to perform two-way data binding is as below:

If you want to change the value in the code by just rewriting the value of the property in the dbrepo object,

At this point, on launching the application you should get below output. Right now, if you enter anything in the Name field, the other two spans would be affected.

cd2

Still, there is scope for much improvement in this code,

  1. Instead of rewriting the innerHtml, append the next text
  2. Extend it for other types than text.

I hope you find this post useful. Thanks for reading.