My mutation takes a useState variable as a parameter and passes it to the Mongoose API to save on MongoDB. I've been trying to get this API to work, but for some reason, I always get a POST http://localhost:4000/graphql 400 (Bad Request)
error.
I'm trying to console.log the mutation input variable server-side but the code never reaches the resolver.
Here's my code:
const ADD_POST = gql`
mutation CreatePost($post: PostInput!) {
createPost(post: $post) {
post
}
}
`;
export default function page() {
const [createPost, {data, loading, error}] = useMutation(ADD_POST)
const [post, setPost] = useState<IPost>({
contactInfo: {
phone: "",
email: "",
sns: {
type: "Twitter",
username: ""
}
},
title: "",
description: "",
})
const handleSubmit = async () => {
//Send "/api/new-post" to process post variable
const { data } = await axios.post("/api/new-post", { post: post });
console.log("NewPost ", data)
console.log("NewPost ", data.post)
// Works up until here
await createPost({variables: {post: data.post} })
router.push('/')
}catch(err: any){
console.log(err.message)
}
};
//sePost function, onChangeHandler and Inputs for each fields here...
<button
type="button"
onClick={()=>handleSubmit()}>
Click
</button>
export const postTypeDefs = `#graphql
scalar JSON
type Post {
_id: ID!
contactInfo: JSON
title: String!
description: String!
}
type Query {
posts: [Post!]!
}
type CreatePostResponse {
success: Boolean!
error: String
}
type Mutation {
createPost(post: PostInput): String
}
input PostInput {
contactInfo: JSON
title: String!
description: String!
}
`;
const dateScalar = new GraphQLScalarType({
export const postResolvers = {
JSON: GraphQLJSON,
Query: {
// Return all posts
posts: async () => {
try {
await connectDB();
const posts = await Post.find();
return posts;
} catch (err) {
console.log(err);
}
},
//Return posts by User's ObjectId
postsByUserId: async (parent, args) => {
const { postedBy } = args;
await connectDB();
const posts = await Post.find();
return posts.filter((post) => post.postedBy.toString() === postedBy);
}
},
Mutation: {
createPost: async (parent, args)=>{
try{
const {post} = args;
// Just want to make this console.log work
console.log("API endpoint", post)
//Add to Mongodb, logic follows...
return { success: true };
}catch(err){
return { success: false, error: err.toString() };
}
}
}
};
import mongoose from 'mongoose';
const postSchema = new mongoose.Schema({
contactInfo: {
phone: { type: String, default: '' },
email: { type: String, default: '' },
sns: {
type: {
type: String,
default: 'Twitter'
},
username: { type: String, default: '' }
}
},
title: { type: String, required: true },
description: { type: String, default: '' },
});
const Post = mongoose.model('Post', postSchema);
export default Post;
The typical source for a 400 error is GraphQL syntax error. That error would happen before your resolver is called. Try the same query in the playground first to make sure it works.
I suspect the issue is that you've defined your CreatePost
schema to return a String
but you've included a field in your mutation result. Try changing:
createPost(post: $post) {
post
}
to
createPost(post: $post)
Also your resolver logic (that is never reached) is attempting to return an object return { success: true };
rather than a string so that will fail next.