I don't know if my question is legit or not, but I am trying to intercept every message from my api for dispose it in a popup via an interceptor :
export class ApiMessageInterceptor implements HttpInterceptor {
constructor(public dialog: MatDialog) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
tap((event: HttpEvent<any>) => {
if (event instanceof HttpResponse && JSON.parse(event.body) instanceof AlertMessage ) { //here I am trying to know if the object in the body is an AlertMessage type or not
this.dialog.open(AlertMessageComponent, {
width: '600px',
data: event.body
});
}
})
);
}
}
But this doesn't work. I mean, my interceptor intercepts the httpresponses very well, I can check the content in the body via the debugger, and everything is ok. But instanceOf check doesn't work at all.
So, any idea of how can I check the object type in the body?
Thanks.
EDIT :
AlertMessage class :
import { AlertMessageType } from "../enum/alert-message.type";
export class AlertMessage {
public content?: string;
public type?: AlertMessageType;
constructor(content?: string, type?: AlertMessageType) {
this.content = content;
this.type = type;
}
}
Body console.log :
{content: "L'identifiant ou le mot de passe est incorrect.", type: 1}
content: "L'identifiant ou le mot de passe est incorrect."
type: 1
[[Prototype]]: Object
EDIT 2 :
I tried something like that :
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
tap((event: HttpEvent<HttpResponse<AlertMessage>>) => {
if (event instanceof HttpResponse && event.body?.body instanceof AlertMessage) {
this.dialog.open(AlertMessageComponent, {
width: '600px',
data: event.body.body
});
}
})
);
}
The first 'body' for HttpResponse type and the second is an AlertMessage Type, recognized as such in VS Code. But when I try it on live, both are undefined :((((
Very bizzare
CodePudding user response:
instanceof
relies on Symbol.hasInstance
which gets set behind the scenes when a constructor is called. JSON.parse
just creates an instance of Object
so it won't match to custom classes by default.
To make instanceof
match arbitrary objects to a custom class you can override the default behaviour like described here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance
You can make it check the types of primitives, or even the instanceof
of other objects. You can run any code to validate that this is the correct object type.
export class AlertMessage {
static [Symbol.hasInstance](instance) {
return (
typeof instance.content === 'string' &&
...
);
}
...
}
I don't know what AlertMessageType
is so I can't add the code to validate that property.
Example
class AlertMessage {
static [Symbol.hasInstance](instance) {
return (
typeof instance.content === 'string' && typeof instance.code === 'number'
);
}
}
console.log({ content: 'test', code: 1 } instanceof AlertMessage);