如何解决未处理的 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 举报,一经查实,本站将立刻删除。