отображение сообщения MatSnackBar при сбое Apollo GraphQL с ошибкой

#angular #angular-material #graphql #apollo

#angular #angular-материал #graphql #apollo

Вопрос:

У меня есть веб-сайт, который использует Angular 10 и Apollo GraphQL.

Всякий раз, когда запрос завершается с ошибкой, я хочу показать ошибку пользователю, который использует MatSnackBar , но я не знаю, как предоставить MatSnackBar компонент OnError() функции apollo-link-error .

Это мой graphql.module.ts код:

 import {NgModule} from '@angular/core';
import {APOLLO_OPTIONS} from 'apollo-angular';
import {ApolloClientOptions, ApolloLink, InMemoryCache} from '@apollo/client/core';
import {HttpLink} from 'apollo-angular/http';
import { onError } from 'apollo-link-error';

function getNewToken(): any {
  //TODO: need to implement
}

const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
    if (graphQLErrors) {
      for (const err of graphQLErrors) {
        switch (err.extensions?.code) {
          case 'UNAUTHENTICATED':
            // error code is set to UNAUTHENTICATED
            // when AuthenticationError thrown in resolver

            // modify the operation context with a new token
            const oldHeaders = operation.getContext().headers;
            operation.setContext({
              headers: {
                ...oldHeaders,
                authorization: getNewToken(),
              },
            });
            // retry the request, returning the new observable
            return forward(operation);
        }
      }
      graphQLErrors.map(({ message, locations, path }) =>
        console.log(
          `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
        ),
      );
    }

    if (networkError) {
      console.log(`[Network error]: ${networkError}`);
      // if you would also like to retry automatically on
      // network errors, we recommend that you use
      // apollo-link-retry
    }
  }
);

const uri = 'http://localhost:8081/graphql';
export function createApollo(httpLink: HttpLink): ApolloClientOptions<any> {
  const httpLinkHandler = httpLink.create({uri});
  const httpLinkWithErrorHandling = ApolloLink.from([
    // @ts-ignore
    errorLink,
    httpLinkHandler,
  ]);

  return {
    link: httpLinkWithErrorHandling,
    cache: new InMemoryCache(),
  };
}

@NgModule({
  providers: [
    {
      provide: APOLLO_OPTIONS,
      useFactory: createApollo,
      deps: [HttpLink],
    },
  ],
})
export class GraphQLModule {}
  

Где я могу отобразить ошибки с помощью console.info ? Вместо этого я хочу показать панель закусок. Есть идеи?

Комментарии:

1. ссылки не предназначены для рендеринга (это не php, где вы можете везде echo "error"; die; )… это часть цепочки обработки запросов / ответов… ответ должен дойти до клиента… приложение, работающее с клиентом, получает информацию об ошибке — используйте эту информацию на уровне приложения… как это было бы с axios?

2. @xadm — могу ли я подписаться на события на панели инструментов и отправить событие отсюда, чтобы панель инструментов перехватила его и отобразила эту панель инструментов?

3. извините, IDK, не работает с Ang.

Ответ №1:

Я нашел решение вскоре после создания награды. таким образом, это всего лишь вопрос внедрения MatSnackbar , копирования его в локальную переменную, которая будет использоваться в объекте error.

Итак, в зависимостях поставщиков я добавил MatSnackBar к зависимостям:

 @NgModule({
  providers: [
    {
      provide: APOLLO_OPTIONS,
      useFactory: createApollo,
      deps: [HttpLink, MatSnackBar],
    },
  ],
})
export class GraphQLModule {}
  

затем в createApollo() функции я скопировал matSnackBar в локальную переменную:

 export function createApollo(httpLink: HttpLink, matSnackBar: MatSnackBar): ApolloClientOptions<any> {
      localMatSnackbar = matSnackBar;
  

затем в onError() обработчике я использовал его при сетевой ошибке:

 if (networkError) {
  localMatSnackbar?.open(networkError.message, 'DISMISS', {
    duration: 2000,
    verticalPosition: 'top'
  });
  

и это все!

Если есть более элегантный способ ее устранения, я буду более чем счастлив принять другой ответ.

Комментарии:

1. Я думаю, что вы отлично суммировали это, и в этом прелесть внедрения зависимостей в Angular.