So, we've got Graphql response handler
export const handleResponse = (operation: DocumentNode): OperatorFunction<any, any> => {
return pipe(
map((response: any) => {
const definition = operation.definitions[0] as OperationDefinitionNode;
const selection = definition.selectionSet.selections[0] as FieldNode;
const selectionName = selection.name.value ?? null;
if (!selectionName) {
throw new Error(`${selection.kind} name must be present.`);
}
if (response.data[selectionName]?.errors) {
handleError(response.data[selectionName].errors);
}
return response.data[selectionName];
}),
);
};
const handleError = (errors: string[]) => {
if (Array.isArray(errors) && errors.length) {
const errorArrayToString = errors.map(error => JSON.stringify(error)).toString();
throw new Error(errorArrayToString);
}
};
It does works pretty well, but I also want to use notification service. I want to do something like that
const handleError = (errors: string[]) => {
if (Array.isArray(errors) && errors.length) {
notificationsService.show('Any error message')
const errorArrayToString = errors.map(error => JSON.stringify(error)).toString();
throw new Error(errorArrayToString);
}
};
CodePudding user response:
You need to inject the service inside a variable
import { Component, Injector, OnInit } from '@angular/core';
import { NotificationsService } from './custom.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent implements OnInit {
// @Constructor services injectors
notificationsService: NotificationsService;
/**
* Constructor
*/
constructor(
private _injector: Injector
) {
this.notificationsService = this._injector.get<NotificationsService>(NotificationsService);
}
ngOnInit(): void {
}
//custom error handler
handleError (errors: string[]) => {
if (Array.isArray(errors) && errors.length) {
this.notificationsService.show('Any error message')
const errorArrayToString = errors.map(error => JSON.stringify(error)).toString();
throw new Error(errorArrayToString);
}
};
}
CodePudding user response:
Thanks, but I decided to move this logic into HTTP interceptor. Here is the code
@Injectable()
export class ApolloErrorInterceptor implements HttpInterceptor {
constructor(private _notificationsService: TuiNotificationsService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
tap((response: any) => {
if (request.body?.operationName) {
const operationName = request.body.operationName;
if (response.body?.data[operationName]?.errors) {
response.body.data[operationName].errors.forEach((error: any) => {
this._notificationsService
.show(error.message, { status: TuiNotification.Error, autoClose: 5000 })
.subscribe();
});
}
}
}),
);
}
}
It will intercept only those responses that have an "operationName" in the body, which is Graphql responses
But now you need to explicitly make sure to specify the name of the request