Apollo Client Mutation get an error 400 with React Component - graphql

Mutation gql tag:
// AppAdminLoinInput is wrong spell don't focus it.
const LOGIN_MUTATION = gql`
mutation AppAdminLoinInput($email: String!, $password: String!) {
appAdminLogin(email: $email, password: $password) {
name
email
token {
accessToken
refreshToken
}
}
}
`;
Mutation Function onSubmit
onSubmitLogin = async (e, appAdminLogin) => {
const { email, password } = this.state;
e.preventDefault();
if (!validator.isEmail(email)) {
console.log("Not email format");
return;
}
if (password.length < 8) {
return;
}
appAdminLogin({
variables: {
email,
password
}
});
};
When onSubmitLogin do i get an error 400 (Bad request)
What am i do wrong?
sorry about my english skill xD

Related

Graphql/bcrypt error "Illegal arguments: string, function"

I am working with graphql to signup/sign in. Registration runs smoothly but I am running into this the bcrypt error upon logging back in. When I change it to user.password in the if statement below the loginUser function, it says throws a newUser is undefined error. Where is my error in this one?
Resolvers:
const resolvers = {
Mutation: {
async registerUser(_, { registerInput: { username, email, password } }) {
const previousUser = await User.findOne({ email });
if (previousUser) {
throw new ApolloError(
"A user with this email already exists" + email,
"User_Already_Exists"
);
}
var encryptedPassword = await bcrypt.hash(password, 10);
const newUser = new User({
username: username,
email: email.toLowerCase(),
password: encryptedPassword,
});
const token = jwt.sign(
{ user_id: newUser._id, email },
"this is the secret",
{
expiresIn: "2h",
}
);
newUser.token = token;
const res = await newUser.save();
return {
id: res.id,
...res._doc,
};
},
async loginUser(_, { loginInput: { email, password } }) {
const user = await User.findOne({ email });
if (user && (await bcrypt.compare(password, user.model))) {
const token = jwt.sign(
{ user_id: newUser._id, email },
"this is the secret",
{
expiresIn: "2h",
}
);
user.token = token;
return {
id: res.id,
...res._doc,
};
You need to compare to user.password not user.model
newUser isn't defined if the passwords match, use user instead.
async loginUser(_, { loginInput: { email, password } }) {
const user = await User.findOne({ email });
if (user && (await bcrypt.compare(password, user.password))) {
const token = jwt.sign(
{ user_id: user._id, email },
"this is the secret",
{ expiresIn: "2h"}
);
user.token = token; // this isn't used anywhere, why?
return {id: res.id,...res._doc}; // this looks wrong too, res is not in scope
}
}

How do I write a Prisma and Apollo resolver to add a user to a chatroom?

When using resolvers in graphql, how to I add items to the arrays with the prisma syntax? And if you understand what I mean, what terminology should I be using?
I have the following graphql mutation:
mutation CreateChatRoom {
createChatroom {
id
}
}
Response: Invalid prisma.chatroom.create()
schema.prisma
model Chatroom {
id Int #id #unique #default(autoincrement())
topic String
members User[]
// *** //
}
model User {
id String #id #default(uuid())
chatrooms Chatroom[]
// *** //
}
TypeDef
type Mutation {
createChatroom(topic: String): Chatroom
}
I have Chatroom, User, and Messages. I'm trying to add a User to Chatroom with the following
Resolver
createChatroom: async (parent, { topic = "" }, { userId, prisma }) => {
const user = await prisma.user.findUnique({
where: {
id: userId
}
}) //is this necissary?
const chatroom = await prisma.chatroom.create({
data: {
members: [user], //put the first user in the Chatroom[]
topic: topic,
messages: []
}
})
return chatroom
},
joinChatroom: async (parent, { chatroomId }, { userId, prisma }) => {
const user = await prisma.user.findUnique({
where: {
id: userId
}
}),
const chatroom = await prisma.chatroom.findUnique({
where: {
id: chatroomId
}
})
// chatroom.update({ add [user, ...users] ? })
},

GraphQL: POST body missing, invalid Content-Type, or JSON object has no keys

I am trying to create a mutation but I keep getting a POST body is missing. I can log the data before urql and codegen hooks are called and I can see the data in the variables on the error, but chrome keeps imploding with a "POST body missing" error and the server's resolver is never hit.
I am using Urql with Codegen on a React Client and using Apollo-server on an Express API.
Here is my code:
Mutation Definition (for codegen)
mutation UserLogin($email: String!, $password: String!) {
login(email: $email, password: $password) {
errors {
email {
error
isValid
}
password {
error
isValid
}
}
token
}
}
codegen outputs:
export const UserLoginDocument = gql`
mutation UserLogin($email: String!, $password: String!) {
login(email: $email, password: $password) {
errors {
email {
isValid
error
}
password {
isValid
error
}
}
token
}
}
`;
export function useUserLoginMutation() {
return Urql.useMutation<UserLoginMutation, UserLoginMutationVariables>(UserLoginDocument);
};
Using this hook fails, so I tried using urql directly:
useMutation Hook (same error)
const [, executeMutation] = useMutation(`
mutation($email: String!, $password: String!) {
login(email: $email, password: $password) {
errors {
email {
error
isValid
}
password {
error
isValid
}
}
token
}
}
`);
I have confirmed that I can execute the query with a raw fetch:
async function fetchGraphQL(text: any, variables: any, token: string = '') {
const response = await fetch('http://localhost:4000/graphql', {
method: 'POST',
headers: {
Authorization: `bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: text,
variables,
}),
});
return await response.json();
}
However, attempts to generate a hook via codegen or just using urql's useMutation hook are resulting in:
{
...
"source": {
"body": "mutation ($email: String! $password: String!) { login(email: $email password: $password) { errors { email { error isValid } password { error isValid } } token } }",
...
},
"variables": {
"email": "...",
"password": "..."
},
"kind": "mutation",
"context": {
"url": "http://localhost:4000/graphql",
"preferGetMethod": false,
"suspense": false,
"requestPolicy": "cache-first",
"meta": {
"cacheOutcome": "miss"
}
}
},
"error": {
"name": "CombinedError",
"message": "[Network] Bad Request",
"graphQLErrors": [],
"networkError": {},
"response": {}
}
}
I have another, very simple mutation that works fine:
mutation SetActiveChild($childId: String!) {
setActiveChild(childId: $childId)
}
Here are my typeDefs and resolvers:
typeDefs
export const typeDefs = gql`
...
type Mutation {
"user login"
login(email: String!, password: String!): LoginResponse
}
...
`
resolvers
export const resolvers = {
Query: {
...
},
Mutation: {
login: ({}, user: UserRegister) => {
return AuthGraph.login(user);
},
...
},
};
I'm pretty new to GraphQL, many thanks in advance to help me understand what I've done wrong.
Add following thing to apolloServer configuration
// This middleware should be added before calling `applyMiddleware`.
app.use(graphqlUploadExpress());
Reference: https://www.apollographql.com/docs/apollo-server/data/file-uploads/
I ran into this issue and turned out that in my request Header my Content-Type was being set as text/html; charset=utf-8 Once I changed that to application/json The problem got solved

GraphQL query ( Apollo client link state ) returns empty object {}

The Query
const GET_MEMBER = gql`
query getMembers {
getMembers #client {
firstname
lastname
__typename
}
}
`
export { GET_MEMBER }
The Resolver:
export default {
resolvers: {
Query: {
getMembers: async (_, variables, { cache }) => {
try {
const res = await apiClient.get('/contacts')
return { ...res.data, __typename: 'Member' }
} catch (e) {
throw e
}
},
},
apiClient is an instance of axios
React App:
<Query query={GET_MEMBER}>
{({ loading, error, data }) => {....
I am getting this warning
and the Query in my React App returns {}
Where should I start to debeg it?

Missing field on cache.writeQuery in Mutation Component?

I'm studying GraphQL Mutation components. I'm doing a mutation that adds a resolution, i.e. a New Year's resolution. Here's the schema:
type Resolution {
_id: String!
name: String!
goals: [Goal]
completed: Boolean
}
type Query {
resolutions: [Resolution]
}
type Mutation {
createResolution(name: String!): {
Resolution
user: String
}
}
Here are the resolution resolvers:
import Resolutions from "./resolutions";
import Goals from "../goals/goals";
import { PubSub } from 'graphql-subscriptions';
export const pubsub = new PubSub();
export default {
Query: {
resolutions(obj, args, { userId }) {
return Resolutions.find({
userId
}).fetch();
}
},
Resolution: {
goals: resolution =>
Goals.find({
resolutionId: resolution._id
}).fetch(),
completed: resolution => {
const goals = Goals.find({
resolutionId: resolution._id
}).fetch();
if (goals.length === 0) return false;
const completedGoals = goals.filter(goal => goal.completed);
return goals.length === completedGoals.length;
}
},
Mutation: {
createResolution(obj, { name }, { userId }) {
if (userId) {
const resolutionId = Resolutions.insert({
name,
userId
});
return Resolutions.findOne(resolutionId);
}
throw new Error("Unauthortized");
}
},
};
Here's the user resolver:
export default {
Query: {
user(obj, args, { user }) {
return user || {};
}
},
User: {
email: user => user.emails[0].address
}
};
Here's the mutation component:
const ResolutionForm = () => {
let input;
let state = {
error: null
};
return (
<Mutation
mutation={CREATE_RESOLUTION}
update={(cache, {data: {createResolution}}) => {
const {resolutions} = cache.readQuery({query: GET_RESOLUTIONS});
cache.writeQuery({
query: GET_RESOLUTIONS,
data: {resolutions: resolutions.concat([createResolution])}
});
}}
>
{(createResolution, {data}) => (
<div>
<form
onSubmit={e => {
e.preventDefault();
createResolution({
variables: {
name: input.value
},
});
input.value = "";
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Submit</button>
</form>
</div>
)}
</Mutation>
);
};
Here's the query that loads all the resolutions when the app launches:
const GET_RESOLUTIONS = gql`
query Resolutions {
resolutions {
_id
name
completed
goals {
_id
name
completed
}
}
user {
_id
}
}
`;
That works fine, but when I run the mutation:
const CREATE_RESOLUTION = gql`
mutation createResolution($name: String!) {
createResolution(name: $name) {
__typename
_id
name
goals {
_id
name
completed
}
completed
}
}
`;
...I get a console log error saying:
Missing field user in {
"resolutions": [
{
"_id": "GKTNgbuiDgiZ4wAFZ",
"name": "testing 123",
.....
How do I get the field user into my mutation response?
The GET_RESOLUTIONS query used is originally from a parent component, App.js. It really contains two separate queries-- one for the resolution and one for the user. The CREATE_RESOLUTION Mutation query and resolver, don't return user data, and I don't yet know how to get them to do that.
But, the Mutation component doesn't need the user data. It only gets upset during the call to cache.writeQuery because GET_RESOLUTIONS is asking for user, and the Mutation resolver isn't returning user.
So the fix seems to be to have a special GET_RESOLUTIONS_FOR_MUTATION_COMPONENT query that doesn't ask for user in the first place:
const GET_RESOLUTIONS_FOR_MUTATION_COMPONENT = gql`
query Resolutions {
resolutions {
_id
name
completed
goals {
_id
name
completed
}
}
}
`;
[.....]
const {resolutions} = cache.readQuery({query: GET_RESOLUTIONS_FOR_MUTATION_COMPONENT});
[.....]
Using that there is no error message asking for user.

Resources