微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

未处理的 GraphQL 订阅错误,在 Angular 聊天组件中使用 apollos subscribeToMore 方法进行订阅时

如何解决未处理的 GraphQL 订阅错误,在 Angular 聊天组件中使用 apollos subscribeToMore 方法进行订阅时

问题描述

我有一个 angular 聊天组件,它通过 graphql 查询从后端获取消息。 在同一个查询中,我订阅了通过 graphql 突变添加新消息时的更新。

消息订阅被编码为聊天组件的一个方法,以便我可以在组件第一次呈现时在 angular 生命周期方法调用它。

根据 apollo 中的文档,这是订阅的常用设置: https://apollo-angular.com/docs/data/subscriptions

当我调用订阅编码到其中的方法时,出现以下错误

“不能使用来自另一个模块或领域的 GraphQLSchema“[object GraphQLSchema]”。 确保 node_modules 中只有一个“graphql”实例 目录。如果不同版本的“graphql”是其他版本的依赖 依赖于模块,使用“分辨率”来确保只安装一个版本。 https://yarnpkg.com/en/docs/selective-version-resolutions 不能同时使用重复的“graphql”模块,因为不同 版本可能具有不同的功能和行为。数据来自一 另一个函数中使用的版本可能会产生混淆和 虚假结果。”

我知道错误来自该方法调用,当我注释掉调用时,错误消失了。 订阅查询后端,所以我知道问题出在客户端。

预期行为

用户在聊天中发送新消息时,服务器会通知订阅解析器(服务器端)发生了消息更新,它会将所有消息实时回火到前端,并且消息应该通过subscribe to more方法返回。

我为解决此问题而采取的步骤

我试着看看这个问题: Duplicate "graphql" modules cannot be used

这让我找到了这个链接https://github.com/graphql/graphql-js/issues/491

对于使用 yarn 作为包管理器的人来说,有一个解决方法,但我不关心,因为我使用的是 npm。

我想可能有一个重复的 graphql 模块,所以我尝试清理我的 package.json 文件删除节点模块并重新安装它们,但没有奏效。

代码示例

聊天组件

import { Component,OnInit } from '@angular/core';
import { Apollo,QueryRef,gql } from 'apollo-angular';

const MESSAGES_SUBSCRIPTION = gql`
   subscription {
     messagesAdded {
      id
      content
      user
    }
  }
`;

const GET_MESSAGES = gql`
   query messages{
     messages {
      id
      content
      user
    }
  } `;


 const POST_MESSAGE = gql`
   mutation($user: String!,$content: String!) {
           postMessage(user: $user,content: $content)
   }`;

export class ChatComponent implements OnInit {

 msgsQuery: QueryRef<any>;
 isShowen: boolean = false;  
 isMinimized: boolean = false;
 msgs: any;
 content:String = '';

 constructor(private apollo: Apollo) {
  this.msgsQuery = this.apollo.watchQuery({
    query: GET_MESSAGES
  });

  this.msgsQuery.valueChanges
  .subscribe(({data}:any) => {
    this.msgs = data.messages;
  });
 }

 ngOnInit(): void {
   //this.subscribetoNewMsgs(); //Error is logged when invoked
 }

 subscribetoNewMsgs() {
   this.msgsQuery.subscribetoMore({
    document: MESSAGES_SUBSCRIPTION,updateQuery: (prev,{subscriptionData}) => {
     if (!subscriptionData.data) {
       return prev;
     }

     const newMsgs = subscriptionData.data.messages;
     console.log(newMsgs)

     return {
      entry: {
        msgs: [...newMsgs,...prev.entry.messages]
      }
     };
    }
  });
 }

 sendMsg(){
  this.apollo.mutate({
    mutation: POST_MESSAGE,variables: {
      user: 'Test',content: this.content
    }
  }).subscribe(({ data }) => {
    console.log('got data',data);
  },(error) => {
    console.log('there was an error sending the query',error);
  });
 }

}

依赖于 package.json 文件

{  
 "dependencies": {
    "@angular/animations": "~10.1.3","@angular/common": "~10.1.3","@angular/compiler": "~10.1.3","@angular/core": "~10.1.3","@angular/forms": "~10.1.3","@angular/platform-browser": "~10.1.3","@angular/platform-browser-dynamic": "~10.1.3","@angular/router": "~10.1.3","@apollo/client": "^3.3.3","@cloudinary/angular-5.x": "^1.3.3","apollo-angular": "^2.2.0","apollo-angular-link-http": "^1.11.0","apollo-cache-inmemory": "^1.6.6","apollo-utilities": "^1.3.4","cloudinary-core": "^2.11.3","graphql": "^15.4.0","ng-image-slider": "^2.6.4","ng2-file-upload": "^1.4.0","react": "^17.0.1","rxjs": "~6.6.0","subscriptions-transport-ws": "^0.9.18","tslib": "^2.0.0","zone.js": "~0.10.2"
 },}

客户端订阅设置根据 apollo 文档进行编码: [查看客户端设置] (https://apollo-angular.com/docs/data/subscriptions)

我没有包含服务器端代码,因为 subscribetoMore 在发送新消息时从不发回数据,因为它遇到了所描述的错误。 我使用的是 Angular v 10.1.6。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。