gpt4 book ai didi

angular - "Cannot return null for non-nullable field"使用 Graphql 订阅 NestJS 时

转载 作者:行者123 更新时间:2023-12-03 23:51:22 26 4
gpt4 key购买 nike

我有一个用 Nestjs 完成的 nodejs 后端我正在使用 Graphql .我的前端是 Ionic/Angular,使用 Apollo-angular 来处理 graphql 的东西。
我在订阅数据添加/更改时遇到问题。 Playground(由 Nestjs 提供)工作得很好,这让我暗示问题出在前端。

我有 gamescores在我的数据模型中,每个分数都属于一个游戏。在前端,我试图聆听添加到特定游戏的新分数。

后端

这是我的片段 resolver :

@Mutation(returns => Score)
async addScore(@Args('data') data: ScoreInput): Promise<IScore> {
return await this.scoresService.createScore(data);
}

@Subscription(returns => Score, {
filter: (payload, variables) => payload.scoreAdded.game + '' === variables.gameId + '',
})
scoreAdded(@Args('gameId') gameId: string) {
return this.pubSub.asyncIterator('scoreAdded');
}

这是 service方法:
async createScore(data: any): Promise<IScore> {
const score = await this.scoreModel.create(data);
this.pubSub.publish('scoreAdded', { scoreAdded: score });
}

这些在我的 schema.gql 中:
type Score {
id: String
game: String
result: Int
}

type Subscription {
scoreAdded(gameId: String!): Score!
}

前端

基于 Apollo-angular的文档,在我的前端我有这样的服务:
import { Injectable } from '@angular/core';
import { Subscription } from 'apollo-angular';
import { SCORE_ADDED } from './graphql.queries';

@Injectable({
providedIn: 'root',
})
export class ScoreListenerService extends Subscription {
document = SCORE_ADDED;
}

这是在前端的 graphql.queries 中:
export const SCORE_ADDED = gql`
subscription scoreAdded($gameId: String!) {
scoreAdded(gameId: $gameId) {
id
game
result
}
}
`;

我在我的组件中使用这样的服务:
this.scoreListener.subscribe({ gameId: this.gameId }).subscribe(({ data }) => {
const score = data.scoreAdded;
console.log(score);
});

问题

有了这一切,我的前端给了我一个错误 ERROR Error: GraphQL error: Cannot return null for non-nullable field Subscription.scoreAdded.
在 Playground 中进行这样的订阅工作,完全没有问题。
subscription {
scoreAdded(gameId: "5d24ad2c4cf6d3151ad31e3d") {
id
game
result
}
}

不同的问题

我注意到如果我使用 resolve在我后端的解析器中,如下所示:
  @Subscription(returns => Score, {
resolve: value => value,
filter: (payload, variables) => payload.scoreAdded.game + '' === variables.gameId + '',
})
scoreAdded(@Args('gameId') gameId: string) {
return this.pubSub.asyncIterator('scoreAdded');
}

前端中的错误消失了,但它搞砸了订阅中的数据,操场在每个属性中获得了带有 null 的附加分数,并且根本不会触发前端中的订阅。

任何帮助,我在这里做错了什么?
在我看来,我的前端不正确,但我不确定这是我的错误还是可能是 Apollo-angular 中的错误...

最佳答案

好的,解决了我的问题。正如我所怀疑的,问题出在前端代码中。所以我在后端实现 nestjs 的方式并没有错。原来是我犯的一个愚蠢的错误,没有为订阅初始化 WS,这里解释清楚 https://www.apollographql.com/docs/angular/features/subscriptions/ .

所以,我改变了这个

const graphqlUri = 'http://localhost:3000/graphql';

export function createApollo(httpLink: HttpLink) {
return {
link: httpLink.create({ graphqlUri }),
cache: new InMemoryCache(),
defaultOptions: {
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all',
},
},
};
}

对此
const graphqlUri = 'http://localhost:3000/graphql';
const wsUrl = 'ws://localhost:3000/graphql';

export function createApollo(httpLink: HttpLink) {
const link = split(
// split based on operation type
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === 'OperationDefinition' && operation === 'subscription';
},
new WebSocketLink({
uri: wsUrl,
options: {
reconnect: true,
},
}),
httpLink.create({
uri: graphqlUri,
})
);
return {
link,
cache: new InMemoryCache(),
defaultOptions: {
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all',
},
},
};
}

关于angular - "Cannot return null for non-nullable field"使用 Graphql 订阅 NestJS 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57336291/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com