PubSub 在客户端页面中不起作用,但在 Graphql 游乐场中起作用 - TypeError: data.getPosts is not iterable
Posted
技术标签:
【中文标题】PubSub 在客户端页面中不起作用,但在 Graphql 游乐场中起作用 - TypeError: data.getPosts is not iterable【英文标题】:PubSub does not work in Client page but works in Graphql playground - TypeError: data.getPosts is not iterable 【发布时间】:2021-02-25 03:55:55 【问题描述】:我正在尝试使用 MongoDB、Express、React、Node、Graphql 和 Apollo 制作一个社交应用程序,我正在关注来自 freecodecamp 的视频:Link to the video
我正在使用 pubsub
来实现实时功能,就像添加新帖子时,它应该会显示在主页中。
我可能错过了某些文件的代码,这就是为什么 我正在删除一个指向包含整个项目的 github 存储库的链接:Link to the github repo
Home.js:
import React, useContext from 'react';
import useQuery from '@apollo/react-hooks';
import Grid, Transition from 'semantic-ui-react';
import AuthContext from '../context/auth';
import PostCard from '../components/PostCard';
import PostForm from '../components/PostForm';
import FETCH_POSTS_QUERY from '../util/graphql';
function Home()
const user = useContext(AuthContext);
const data, loading, error = useQuery(FETCH_POSTS_QUERY);
if(data)
const posts = data || [];
return (
<Grid columns=3>
<Grid.Row className="page-title">
<h1>Recent Posts</h1>
</Grid.Row>
<Grid.Row>
user && (
<Grid.Column>
<PostForm />
</Grid.Column>
)
loading && <h1>Loading posts..</h1>
data && (
<Transition.Group>
posts &&
posts.map((post) => (
<Grid.Column key=post.id style= marginBottom: 20 >
<PostCard post=post />
</Grid.Column>
))
</Transition.Group>
)
</Grid.Row>
</Grid>
);
if(error)
return error.message;
export default Home;
我渲染了Home.js
中的所有帖子
解析器 => posts.js :
const AuthenticationError, UserInputError = require('apollo-server');
const Post = require('../../models/Post');
const checkAuth = require('../../util/check-auth');
module.exports =
Query:
async getPosts()
try
const posts = await Post.find().sort( createdAt: -1 );
return posts;
catch (err)
throw new Error(err);
,
async getPost(_, postId )
try
const post = await Post.findById(postId);
if (post)
return post;
else
throw new Error('Post not found');
catch (err)
throw new Error(err);
,
Mutation:
async createPost(_, body , context)
const user = checkAuth(context);
if (body.trim() === '')
throw new Error('Post body must not be empty');
const newPost = new Post(
body,
user: user.id,
username: user.username,
createdAt: new Date().toISOString()
);
const post = await newPost.save();
context.pubsub.publish('NEW_POST',
newPost: post,
).then(()=>
console.log("working")
);
return post;
,
async deletePost(_, postId , context)
const user = checkAuth(context);
try
const post = await Post.findById(postId);
if (user.username === post.username)
await post.delete();
return 'Post deleted successfully';
else
throw new AuthenticationError('Action not allowed');
catch (err)
throw new Error(err);
,
async likePost(_, postId , context)
const username = checkAuth(context);
const post = await Post.findById(postId);
if (post)
if (post.likes.find((like) => like.username === username))
// Post already likes, unlike it
post.likes = post.likes.filter((like) => like.username !== username);
else
// Not liked, like post
post.likes.push(
username,
createdAt: new Date().toISOString()
);
await post.save();
return post;
else throw new UserInputError('Post not found');
,
Subscription:
newPost:
subscribe: (_, __, pubsub ) => pubsub.asyncIterator('NEW_POST')
;
解析器 => index.js :
const postsResolvers = require('./posts');
const usersResolvers = require('./users');
const commentsResolvers = require('./comments');
module.exports =
Post:
likeCount: (parent) => parent.likes.length,
commentCount: (parent) => parent.comments.length
,
Query:
...postsResolvers.Query
,
Mutation:
...usersResolvers.Mutation,
...postsResolvers.Mutation,
...commentsResolvers.Mutation
,
Subscription:
...postsResolvers.Subscription
;
tyDefs.js:
const gql = require('apollo-server');
module.exports = gql`
type Post
id: ID!
body: String!
createdAt: String!
username: String!
comments: [Comment]!
likes: [Like]!
likeCount: Int!
commentCount: Int!
type Comment
id: ID!
createdAt: String!
username: String!
body: String!
type Like
id: ID!
createdAt: String!
username: String!
type User
id: ID!
email: String!
token: String!
username: String!
createdAt: String!
input RegisterInput
username: String!
password: String!
confirmPassword: String!
email: String!
type Query
getPosts: [Post]
getPost(postId: ID!): Post
type Mutation
register(registerInput: RegisterInput): User!
login(username: String!, password: String!): User!
createPost(body: String!): Post!
deletePost(postId: ID!): String!
createComment(postId: String!, body: String!): Post!
deleteComment(postId: ID!, commentId: ID!): Post!
likePost(postId: ID!): Post!
type Subscription
newPost(
id: ID!,
body: String!,
createdAt: String!,
username: String!,
likeCount: Int!,
commentCount: Int!): Post!
`;
这是我的服务器(后端)的 index.js 文件:
const ApolloServer, PubSub = require('apollo-server');
const mongoose = require('mongoose');
const typeDefs = require('./graphql/typeDefs');
const resolvers = require('./graphql/resolvers');
const MONGODB = require('./config.js');
const pubsub = new PubSub();
const PORT = process.env.port || 5000;
const server = new ApolloServer(
typeDefs,
resolvers,
context: ( req ) => ( req, pubsub )
);
mongoose
.connect(MONGODB, useUnifiedTopology: true , useNewUrlParser: true )
.then(() =>
console.log('MongoDB Connected');
return server.listen( port: PORT );
)
.then((res) =>
console.log(`Server running at $res.url`);
)
.catch(err =>
console.error(err)
)
我只在 index.js 文件中初始化 pubsub, 这是我得到的错误:
TypeError: data.getPosts is not iterable 0.chunk.js:124321
错误截图:
此错误是一个问题,另一个问题是,每当我单击提交时,都会发生相同的错误,但是当我在Graphql
Playground 中运行订阅时,帖子出现在客户端页面中,但当我刷新页面时,帖子出现在那里.
【问题讨论】:
为什么每个人都不想回答我的问题,我已经被这个错误困扰了好几个小时了。我是否应该对我的问题进行任何更改,例如添加一些代码而不是 github 存储库?? 你需要把你尝试过的代码放在图片/视频/githubs上 谢谢我把代码放上去,因为代码太多所以没有放 @Naren 我已经添加了一些文件的代码,如果您想添加更多文件,我会添加它。 根据错误消息,我会说,您的data.getPosts()
不会像您期望的那样返回数组。你能记录下它的输出并查看实际返回的内容吗?
【参考方案1】:
如果您使用的是 Apollo v3,并且在添加帖子时遇到了一些缓存问题:
const [createPost, error ] = useMutation(CREATE_POST_MUTATION,
variables: values,
update(proxy, result)
const data = proxy.readQuery(
query: FETCH_POSTS_QUERY,
);
proxy.writeQuery(
query: FETCH_POSTS_QUERY,
data:
getPosts: [result.data.createPost, ...data.getPosts],
,
);
values.body = "";
,
onError(err)
<== also add this so the page doesn't break
return err;
,
);
【讨论】:
以上是关于PubSub 在客户端页面中不起作用,但在 Graphql 游乐场中起作用 - TypeError: data.getPosts is not iterable的主要内容,如果未能解决你的问题,请参考以下文章
一个函数在我用 Postman 测试时有效,但在我的客户中不起作用
p12 在 NodeDefaultKeyStore 中工作,但在 WebSphere 的 CellDefaultKeyStore 中不起作用