Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

json - Parse date with Angular 4.3 HttpClient

I'm currently switching to the new HttpClient of Angular 4.3. One advantage is that I can specify a type info on the GET method and that the returned JSON is parsed into the given type, e.g.

this.http.get<Person> (url).subscribe(...)

But unfortunately, all dates in the JSON are parsed as numbers in the resulting object (probably because the Java Date objects are serialized as numbers in the backend).

With the old Http I used a reviver function when calling JSON.parse() like this:

this.http.get(url)
  .map(response => JSON.parse(response.text(), this.reviver))

and in the reviver function I created date objects from the numbers:

reviver (key, value): any {
  if (value !== null && (key === 'created' || key === 'modified'))
    return new Date(value);

  return value;
}

Is there a similar mechanism with the new HttpClient? Or what is the best practice to do conversion when the JSON is parsed?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This works for me:

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

@Injectable()
export class ApiInterceptor implements HttpInterceptor {
  private dateRegex = /^(d{4})-(d{2})-(d{2})T(d{2}):(d{2}):(d{2}(?:.d*)?)$/;

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

  constructor() { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request)
      .do((event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
          this.convertDates(event.body);
        }
      });
  }

  private convertDates(object: Object) {
    if (!object || !(object instanceof Object)) {
      return;
    }

    if (object instanceof Array) {
      for (const item of object) {
        this.convertDates(item);
      }
    }

    for (const key of Object.keys(object)) {
      const value = object[key];

      if (value instanceof Array) {
        for (const item of value) {
          this.convertDates(item);
        }
      }

      if (value instanceof Object) {
        this.convertDates(value);
      }

      if (typeof value === 'string' && this.dateRegex.test(value)) {
        object[key] = new Date(value);
      }
    }
  }
}

The advantage of this over the answer of bygrace is that you don't need to parse to json yourself, you just convert the dates after angular is done with the parsing.

This also works with arrays and nested objects. I modified this it should support arrays.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...