-
-
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); | |
} | |
} |
Stared!
Wondering if a solution to this problem already exists in core Angular. Maybe in latest or future versions.
Can't believe there isn't an embedded solution with Angular...
This rescured my life. Thank you very much mate.
I think I'm on love <3
I can't believe I worked without this interceptor so far.
Thanks a lot dude ;-)
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.
do you think that this interceptor will not cause some performance problems ? say, we have an http response that contains a list of 1000 iso date