DEV Community

Ben
Ben

Posted on • Edited on

Date Handling in Angular Application (Part 2 - Angular Http Client and Ngx Datepicker)

Original Post: https://medium.com/self-learning/date-handling-in-angular-application-part-2-angular-http-client-interceptor-and-ngx-datepicker-bf32231010f8

Introduction

The below is a summary of previous post about JavaScript Date Object and JSON Date.

  • JSON is common communication format between server side and client side
  • JavaScript Date Object is Time zone and Locale Dependent
  • ISO 8601 Date Format is a general agreement for JSON Date representation
  • JavaScript do not know JSON date type. Conversion between JSON Date String and JavaScript Date Object is required.

Seamless Integration Approaches

In Angular Application, what could be done in order to make the seamless integration of JavaScript Date Object, JSON and UI Components?

There would be two important parts for the seamless integration.

  • Communication between Client Side and Server Side
  • Datepicker Handling

Communication between Client Side and Server Side

In Angular Application, it would provide HttpClientModule for simplifying HTTP Communication between client side and server side.

this.httpClient.get<DataModel>("/api/getData").subscribe(
  (data: DataModel) => {
    console.log(data);
  }
);
Enter fullscreen mode Exit fullscreen mode

Although, the data model (Interface) is defined above, JSON does not have date object. The date object would be presented as Data String in ISO format. The Data String would simply assign to date even though it is defined as Date in Interface in TypeScript. Note that the interface would be compiled to nothing and it is only for tying checking in typescript context.

interface DataModel {
  data1: string; 
  data2: string; 
  data3: string
  date1: Date; 
  date2: Date; 
  date3: Date
}
Enter fullscreen mode Exit fullscreen mode

There would be two approaches to convert

  • Http Client Pipe
  • Angular Http Interceptor

Http Client Pipe

Http Client would return Observable for various provided method. The map operator in pipe could be used to convert date string to date object.

this.httpClient.get<DataModel>("/api/getData")
  .pipe(
    map((data)=>{
      data.date1 = new Date(data.date1);
      data.date2 = new Date(data.date2);
      data.date3 = new Date(data.date3);
      return data;
    })
  ).subscribe(
    (data: DataModel) => {
      console.log(data);
    }
  );
Enter fullscreen mode Exit fullscreen mode

Angular Http Interceptor

As the date string is in ISO 8601, we want to have a generic way to do all the conversion. A custom HttpInterceptor would be added to Angular Application for intercepting request and response.

import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export class JsonDateInterceptor implements HttpInterceptor {


  private _isoDateFormat = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d*)?Z$/;

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(map( (val: HttpEvent<any>) => {
      if (val instanceof HttpResponse){
        const body = val.body;
        this.convert(body);
      }
      return val;
    }));
  }


  isIsoDateString(value: any): boolean {
    if (value === null || value === undefined) {
      return false;
    }
    if (typeof value === 'string'){
      return this._isoDateFormat.test(value);
    }    return false;
  }
  convert(body: any){
    if (body === null || body === undefined ) {
      return body;
    }
    if (typeof body !== 'object' ){
      return body;
    }
    for (const key of Object.keys(body)) {
      const value = body[key];
      if (this.isIsoDateString(value)) {
        body[key] = new Date(value);
      } else if (typeof value === 'object') {
        this.convert(value);
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
this._httpClient.post<Value>("/api/posts", this.value)
  .subscribe((val: Value) => {
    console.log(val.date1);
  });
Enter fullscreen mode Exit fullscreen mode

Angular UI Datepicker

The Date Object in Browser is timezone and locale dependent. Sometimes, we would like to have custom presentation of date which in defined in the web application. We do not want to care about the browser setting.

TO BE CONTINUED

https://medium.com/self-learning/ngx-datepicker-utc-datepicker-design-77e33789e9d7

Reference

Top comments (0)