4

问题描述

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

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

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

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

"Cannot use GraphQLSchema "[object GraphQLSchema]" from another module or realm. 确保 node_modules 目录中只有一个 "graphql" 实例。如果不同版本的 "graphql" 是其他依赖模块的依赖,使用 " resolutions”以确保只安装一个版本。 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。

4

0 回答 0