GraphQL error: Cannot query field 'mutation_name' on type 'Mutation'
Asked Answered
B

3

25

I am trying to mutate a mutation. The mutation does exist and works fine on my graphql playground. but as I implement it in my react component, I get error. Queries work fine though. By the way, I need client in my code so I definitely have to use ApolloConsumer.

I tried using client.mutate like https://github.com/apollographql/apollo-client/issues/2762

export const LOGIN = gql`
  mutation LOGIN($email: String!, $password: String!) {
    login(email: $email, password: $password) {
      email
    }
  }
`;
class LoginComponent extends Component{
  render(){
    return(
      <ApolloConsumer>
        {client=>{
          return(
            <Button onClick={()=>{
              client
                .mutate({
                  mutation: LOGIN,
                  variables: {
                    email: "[email protected]",
                    password: "test"
                    }
                })
                .then(result => {
                  console.log('result', result)
                })
                .catch(err => {
                  console.log("err", err);
                  alert(err.toString());
                });
            }}> 
              OK
            </Button>
          )
        }}
      </ApolloConsumer>
    )  
  }
}

I expect to get success but I get Error: GraphQL error: Cannot query field 'login' on type 'Mutation'. (line 2, column 3): login(email: $email, password: $password) { ^

Bersagliere answered 1/5, 2019 at 8:46 Comment(3)
seems like there is no such mutation in the schema, perhaps a typo or you need to restart the server if you have added itDillingham
i just restarted my server and it works. ThanksBersagliere
Same issue here but running Android emulator. Graphql playground worked but emulator didn't. Restarted emulator and it worked.Dys
V
2

My mistake was trivial: I was using type-graphql and apollo-server in the backend but added the datasource instead of the correct resolver in the resolvers field:


const schema = await buildSchema({
    resolvers: [
      FirstResolver,
      SecondResolver,
      // added datasource instead of resolver
      ThirdDataSource,
      FourthResolver,
]})

Replacing datasource with the resolver solved the issue.

Package versions:

    "apollo-datasource": "^3.0.3",
    "type-graphql": "^1.1.1",
    "apollo-server-core": "^3.6.2",
Vincenza answered 15/7, 2022 at 10:42 Comment(0)
R
0

Same issue here, I want to add my 2 cents as an answer:

I have several "context" for different endpoint for different GraphQL servers.

I was using the mutation hook like:

const THE_QUERY_OR_MUTATION_CODE = gql`
  mutation {
    myMutation(etc) {
    _id
    etc
  }
}`

const [handlerOrCaller, { loading, error, data } ] =
  useMutation(THE_QUERY_OR_MUTATION_CODE);

In that way I wasn't giving it the correct "context" so Apollo Client was taking the first context found, which was of course another endpoint, and there the schema of course doesn't have that mutation called myMutation.

The config of my Apollo Client is:

const client = new ApolloClient({
  cache: new InMemoryCache({
    dataIdFromObject: (object) => object.key || null
  }),
  link: authLink.concat(splitOne)
});

That splitOne is a concatenated var made with different endpoints in this way:

const endpointALink = createHttpLink({
  uri: process.env.REACT_APP_ENDPOINT_A
});

const ednpointBLink = createUploadLink({
  uri: process.env.REACT_APP_ENDPOINT_B
});

const endpointCLink = createUploadLink({
  uri: process.env.REACT_APP_ENDPOINT_C
});

const endpointDLink = createHttpLink({
  uri: process.env.REACT_APP_ENDPOINT_D
});

const splitThree = split(
  (operation) => operation.getContext().clientName === 'context_a',
  endpointA,
  endpointB
);

const splitTwo = split(
  (operation) => operation.getContext().clientName === 'context_b',
  endpointC,
  splitThree
);

const splitOne = split(
  (operation) => operation.getContext().clientName === 'context_c',
  endpointD,
  splitTwo
);

SO the correct way, in my case, was using the correct context:

const [handlerOrCaller, { loading, error, data } ] =
  useMutation(THE_QUERY_OR_MUTATION_CODE, {
  context: { clientName: 'context_c' }
});
Radiobroadcast answered 1/3, 2022 at 1:22 Comment(0)
S
0

I think your mutation is not structured correctly. I rewrote your code to use async/await since and to import mutations from @apollo/client instead of graphql-tag. I don't have the full context, so use this and let me know if it still doesn't work.

import React, { Component } from 'react';
import { ApolloConsumer } from '@apollo/client';
import gql from 'graphql-tag';

const LOGIN = gql`
  mutation LOGIN($email: String!, $password: String!) {
    login(email: $email, password: $password) {
      email
    }
  }
`;

class LoginComponent extends Component {
  render() {
    return (
      <ApolloConsumer>
        {client => {
          return (
            <button
              onClick={async () => {
                try {
                  const { data } = await client.mutate({
                    mutation: LOGIN,
                    variables: {
                      email: '[email protected]',
                      password: 'test',
                    },
                  });

                  console.log('data', data);
                } catch (error) {
                  console.error('error', error.message);
                  alert(error.message);
                }
              }}
            >
              OK
            </button>
          );
        }}
      </ApolloConsumer>
    );
  }
}

export default LoginComponent;
Spinescent answered 19/12, 2023 at 17:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.