-
-
Save martinobordin/39bb1fe3400a29c1078dec00ff76bba9 to your computer and use it in GitHub Desktop.
import { Injectable } from '@angular/core'; | |
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse, HttpResponse } from '@angular/common/http'; | |
import { Observable } from 'rxjs/Observable'; | |
import 'rxjs/add/operator/do'; | |
@Injectable() | |
export class AngularDateHttpInterceptor implements HttpInterceptor { | |
// Migrated from AngularJS https://raw.githubusercontent.com/Ins87/angular-date-interceptor/master/src/angular-date-interceptor.js | |
iso8601 = /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(([+-]\d\d:\d\d)|Z)?$/; | |
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | |
return next.handle(req).do((event: HttpEvent<any>) => { | |
if (event instanceof HttpResponse) { | |
const body = event.body; | |
this.convertToDate(body); | |
} | |
}, (err: any) => { | |
if (err instanceof HttpErrorResponse) { | |
if (err.status === 401) { | |
} | |
} | |
}); | |
} | |
convertToDate(body) { | |
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.isIso8601(value)) { | |
body[key] = new Date(value); | |
} else if (typeof value === 'object') { | |
this.convertToDate(value); | |
} | |
} | |
} | |
isIso8601(value) { | |
if (value === null || value === undefined) { | |
return false; | |
} | |
return this.iso8601.test(value); | |
} | |
} | |
import { | |
HttpRequest, | |
HttpHandler, | |
HttpEvent, | |
HttpInterceptor, | |
HttpErrorResponse, | |
HttpResponse | |
} from '@angular/common/http'; | |
import { Observable } from 'rxjs'; | |
import { tap } from 'rxjs/operators'; | |
export class AngularDateHttpInterceptor implements HttpInterceptor { | |
// Migrated from AngularJS https://raw.githubusercontent.com/Ins87/angular-date-interceptor/master/src/angular-date-interceptor.js | |
iso8601 = /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(([+-]\d\d:\d\d)|Z)?$/; | |
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | |
return next.handle(req).pipe( | |
tap((event: HttpEvent<any>) => { | |
if (event instanceof HttpResponse) { | |
const body = event.body; | |
this.convertToDate(body); | |
} | |
}, (err: any) => { | |
if (err instanceof HttpErrorResponse) { | |
if (err.status === 401) { | |
} | |
} | |
}), | |
); | |
} | |
convertToDate(body) { | |
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.isIso8601(value)) { | |
body[key] = new Date(value); | |
} else if (typeof value === 'object') { | |
this.convertToDate(value); | |
} | |
} | |
} | |
isIso8601(value) { | |
if (value === null || value === undefined) { | |
return false; | |
} | |
return this.iso8601.test(value); | |
} | |
} |
Can anybody confirm this is working in Angular > 7?
Can anybody confirm this is working in Angular > 7?
It uses the legacy RxJS syntax, so it won't work out of the box. There's this fork that works.
I added also the RxJs6+ syntax (used pipe method & tap operator instead of do)
Thank you so much man!!
I don't understand how that's not a core feature…
For each request, it process all fields and make/try a conversion. Dit someone check for performance ? i'm sure it is performance issue that Angular team do not include it on core.
Thanks for these useful snippets!
Just a heads up...the return body;
statements in convertToDate()
aren't ever used, and don't match up with the final return (void) later on.
Thank you for this!
One thing I think would be good to add is a type check inside the isIso8601 method:
isIso8601(value) {
if (value === null || value === undefined) {
return false;
}
if (typeof value === 'string') {
return this.iso8601.test(value);
}
return false;
}
This way, we can avoid checking at least some of the fields. I've tested this interceptor, and the worst case I've got so far is a 1ms time difference between beginning and ending conversion.
@LAIves91
I added your suggestion in https://gist.github.com/datze/1484eb8535871b4ab72fc81e3ff1c571
I have refactored by making it "type-safe", useful for those using strict typescript mode
Here is the code: https://gist.github.com/aml360/7e8efc275b0adb46bd5bb1b555b42467
For those, like me, who are using Java backends, there's one thing to be aware: the regex used works with LocalDateTime but if any DTO uses LocalDate, those fields won't be converted. I added another regex in order for them to be intercepted aswell.
Glad I found your code but I have one issue on my end. I'm using SpringBoot in the middle tier. How do I have my web service send a ISO8601 format string date in the JSON output? Right now its coming across as a number. I do want keep the field in the pojo as a java.util.Date class.
I think I'm on love <3
I can't believe I worked without this interceptor so far.
Thanks a lot dude ;-)