当 Apollo GraphQL 因错误而失败时显示 MatSnackBar 消息

showing MatSnackBar message when Apollo GraphQL fails with an error

我有一个使用 Angular 10 和 Apollo GraphQL 的网站。

每当请求失败时,我想向使用 MatSnackBar 的用户显示错误,但我不知道如何向 OnError() 函数提供 MatSnackBar 组件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 的错误?我想展示一个小吃店。有什么想法吗?

我创建赏金后很快就找到了解决方案。所以只需要注入 MatSnackbar,将其复制到要在错误对象中使用的局部变量即可。

所以在提供者依赖项中,我将 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'
  });

就是这样!

如果有更优雅的解决方法,我会很乐意接受不同的答案。