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

ufk*_*ufk 5 apollo angular-material graphql angular

我有一个使用 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 {}
Run Code Online (Sandbox Code Playgroud)

我在哪里使用显示错误console.info?我想展示一家小吃店。有任何想法吗?

ufk*_*ufk 4

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

因此,在提供程序依赖项中,我将以下添加MatSnackBar到依赖项中:

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

然后在createApollo()函数中我将其复制matSnackBar到局部变量:

export function createApollo(httpLink: HttpLink, matSnackBar: MatSnackBar): ApolloClientOptions<any> {
      localMatSnackbar = matSnackBar;
Run Code Online (Sandbox Code Playgroud)

然后在onError()处理程序中我在网络错误上使用了它:

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

就是这样!

如果有更优雅的方法来解决它,我将非常乐意接受不同的答案。