You can just implement an HttpInterceptor and intercept the response and mutate the body as you wish before it's return to the caller.
I'm doing something similar to intercept Microsoft ASP.NET format dates returned from my API and turning them into actual Date instances.
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpInterceptor, HttpRequest, HttpResponse, HttpErrorResponse, HttpHandler, HttpEvent } from '@angular/common/http';
@Injectable()
export class Interceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do(event => {
if (event instanceof HttpResponse) {
const resp: HttpResponse<any> = event;
// Mutate the body, replace ASP.NET Dates with actual local Date objects.
let body: {} = resp.body;
this.recurseBody(body);
}
});
}
private recurseBody(body: {}) {
if (!body) {
return;
}
for (let key in body) {
if (body.hasOwnProperty(key)) {
let element = body[key];
if (typeof element === 'object') {
this.recurseBody(element);
} else if (typeof element === 'string') {
// Check for a MS-format Date with optional TZ offset.
const matched = /\/Date\(([-]?\d{1,15})([\+-][01][0-3][0-5][0-9])?\)\//.exec(element);
if (matched) {
let tzOffsetMs = 0;
const tz = matched[2] || '';
if (tz) {
const hours = parseInt(tz.substr(0, tz.length - 2), 10);
const mins = parseInt(tz.substr(tz.length - 2, 2), 10);
const tzOffsetMins = mins + hours * 60;
tzOffsetMs = tzOffsetMins * 60 * 1000;
}
// Create a UTC Date object.
const date = new Date(+matched[1] + tzOffsetMs);
// Get the timezone offset for the local time (in minutes) and convert to ms.
const tzOffset = date.getTimezoneOffset() * 60 * 1000;
// Create a local date by using the offset
const localDate = new Date(date.getTime() + tzOffset);
console.log('convert ' + element + ' to ' + date + ' offset ' + date.getTimezoneOffset() + ' local = ' + localDate);
// Set the local date.
body[key] = localDate;
}
}
}
}
}
}