angular - Apollo GraphQL がエラーで失敗したときに MatSnackBar メッセージを表示する

okwaves2024-01-25  6

私は Angular 10 と Apollo GraphQL を使用する Web サイトを持っています。

リクエストが失敗するたびに、MatSnackBar を使用しているユーザーにエラーを表示したいのですが、MatSnackBar コンポーネントを apollo-link-error の OnError() 関数に提供する方法がわかりません。

これは私の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 を使用してどこでエラーを表示すればよいですか?代わりにスナックバーを表示したいと思います。何かアイデアはありますか?

リンクはレンダリング用ではありません (どこでも「エラー」をエコーできる php ではありません) ... これはの一部ですリクエスト/レスポンス処理、チェーン ... レスポンスはクライアントに到達する必要があります ... クライアントと連携するアプリはエラー情報を取得します - この情報はアプリ層で消費します ... axios ではどうなるでしょうか?

– xadm

2020 年 9 月 3 日 19:57

@xadm - ツールバーでイベントをサブスクライブし、ここからイベントを送信して、ツールバーがそれをキャッチしてマットスナックバーを表示できますか?

– ufk

2020 年 9 月 3 日 20:21

申し訳ありません、IDK さん、Ang では動作しません。

– xadm

2020 年 9 月 3 日 20:24



------------------------

報奨金を作成してすぐに解決策を見つけました。したがって、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'
  });

それで終わりです!

それを解決するもっとエレガントな方法があるなら、私はもっとそうするでしょう別の回答を喜んで受け入れます。

2020 年 9 月 12 日 18:54 に回答

ufk

ufk

31.4k

71 個

71 個の金バッジ

241 個

シルバーバッジ 241 個

394 個

ブロンズ 394 個バッジ

1

1

これを完璧にまとめたと思います。これが依存関係注入の美しさです。Angular でオンにします。

– アフマド アルフィー

2022 年 7 月 22 日 14:32

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。