6

When I manually write the mutation query (in graphql plugin), it's working:

mutation {
                    createExam(input: {
                      data: {
                        name: "myName"
                        desription: "ggg"
                        questions: [{gf: "hello"}]
                        time: 2
                        subjects: ["5c468e2d61670b25b46ccdfe"]
                      }
                    }) {
                      exam {
                        name
                                desription
                        time

                      }
                    }
                  }

But if I code it and pass the exact same array I get an array of the exact same object I get [null, null]

let parsedQuestion = [{gf: "hello"}];

 const response = await strapi.request('POST', '/graphql', {
            data: {
                query: `mutation {
                    createExam(input: {
                      data: {
                        name: "` + examInfo.newExamName + `"
                        desription: "` + examInfo.newExamDescription + `"
                        time: ` + Number(examInfo.newExamTime) + `,
                        questions: `+ parsedQuestion + `, 
                        subjects: ["` + this.state.modalSubject._id + `"]
                      }
                    }) {
                      exam {
                        name
                        desription
                        time
                        questions

                      }
                    }
                  }`
            }

How can it be? Could it be a bug? I also tried with JSON.stringify but then got an error and the mutation didn't even come through

Thanks a lot in advance

sir-haver
  • 3,096
  • 7
  • 41
  • 85

1 Answers1

8

Constructing a query string this way is error-prone and dangerous; it opens you up to a slew of bugs and well-known security vulnerabilities. (What if newExamName is My "super-duper" exam!!!?)

GraphQL provides variables as a better approach to pass data in. In your case since you have a complex somewhat structured object, it's probably easiest to pass the whole input in as one object (other syntaxes are possible). I would expect this to look something like:

const response = await strap.request('POST', '/graphql', {
  data: {
    query: `mutation CreateExam($input: CreateExamInput!) {
      createExam(input: $input) {
        exam { name, desription, time, questions }
      }
    }`,
    variables: {
      input: {
        name: examInfo.newExamName,
        desription: examInfo.newExamDescription,
        time: Number(examInfo.newExamTime),
        questions: [{gf: "hello"}],
        subjects: [this.state.modalSubject._id]
      }
    }
  }
});

Now the HTTP client library can take responsibility for producing well-formed JSON from your input, and you're not performing tricky string manipulation.

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Thanks a lot David I didn't have time to check it yet but it seems like you really helped me understand how to structure the queries thanks a lot – sir-haver Jan 30 '19 at 13:40
  • Hey David, unfortunately this exact code is not working and I'm receiving 'bad request'. Do you know what could cause it? Maybe it's because graphql plugin in strapi has a slightly different syntax? I tried ti play around with it but no success at all – sir-haver Feb 02 '19 at 02:27
  • The most obvious thing I can think of is that I just kind of made up the name of the GraphQL input type in the mutation, but you should get a GraphQL error to that effect. – David Maze Feb 02 '19 at 02:35
  • 1
    I know is an old question but you got bad request because input variables needs a "data" object key `variables { input : { data : { ... all vars }}}` – Nico Sep 26 '19 at 13:16
  • Can't believe GQL got so popular being this much boilerplate... – Eggon Aug 05 '21 at 17:31