For debugging purposes, you can provide an Angular HttpInteceptor
that logs time of every http request made by the Angular app. Btw. it can also indicate if the response was already sent to the client by the ExpressJS engine (e.g. due to a SSR request timeout).
See the example implementation:
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Inject, InjectionToken, Optional } from '@angular/core';
import { RESPONSE } from '@nguniversal/express-engine/tokens';
import { Response } from 'express';
export class LoggingInterceptor implements HttpInterceptor {
constructor(@Optional() @Inject(RESPONSE) private response: Response) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const started = Date.now();
return next.handle(request).pipe(
tap(
_event => {
console.log(
`Request for ${request.urlWithParams} took ${Date.now() - started} ms. ` +
`Was ExpressJS Response already sent?: ${this.response?.headersSent}`
);
},
_error => {
console.log(
`Request for ${request.urlWithParams} failed after ${Date.now() - started} ms. ` +
`Was ExpressJS Response already sent?: ${this.response?.headersSent}`
);
}
)
);
}
}
Explanation:
- we inject
RESPONSE
InjectionToken from @nguniversal/express-engine/tokens
- the
RESPONSE
object has a type of Response
from ExpressJS. Please mind to write: import {Response} from 'express'
. Otherwise the global type Response
of Node.js will be implicitly used, which would be incorrect
- We inject
RESPONSE
with @Optional()
decorator as it is not available in the browser, but only in SSR
- we lookup the property
this.response.headersSent
, which indicates whether the ExpressJS already sent a response to a client. For more, see docs of ExpressJS Response.headersSent
Note: If you want to also console.log the URL of the currently rendered page in SSR, you can inject WindowRef
from @spartacus/core
and log it’s property windowRef.location.href
.