Skip to content Skip to sidebar Skip to footer

Graphql Mutation That Accepts An Array Of Dynamic Size And Common Scalar Types In One Request

I need to be able to create a user and add it's favourite movies (An array of objects with a reference to the Movies collection and his personal rating for each movie) in a single

Solution 1:

You can pass an array like this

var MovieSchema = `
  type Movie {
   name: String
  }
  input MovieInput {
   name: String
  }
  mutation {
   addMovies(movies: [MovieInput]): [Movie]
  }
`

Then in your mutation, you can pass an array like

mutation {
  addMovies(movies: [{name: 'name1'}, {name: 'name2'}]) {
    name
  }
}

Haven't tested the code but you get the idea

Solution 2:

I came up with this simple solution - NO JSON used. Only one input is used. Hope it will help someone else.

I had to add to this type:

typeOption {
    id:ID!status:String!products: [Product!]!
}

We can add to mutation type and add input as follows:

typeMutation {
    createOption(data: [createProductInput!]!):Option!//othermutationdefinitions
}

inputcreateProductInput {
    id:ID!name:String!price:Float!producer:ID!status:String
}

Then following resolver could be used:

const resolvers = {
    Mutation: {
      createOption(parent, args, ctx, info) {

        const status = args.data[0].status;

        // Below code removes 'status' from all array items not to pollute DB.// if you query for 'status' after adding option 'null' will be shown. // But 'status': null should not be added to DB. See result of log below.
        args.data.forEach((item) => {
            delete item.status
        });

        console.log('args.data - ', args.data);

        const option = {
            id: uuidv4(),
            status: status,  // or if using babel    status,products: args.data
        }

        options.push(option)

        return option
      },
    // other mutation resolvers
    }

Now you can use this to add an option (STATUS is taken from first item in the array - it is nullable):

mutation{
  createOption(data:
    [{
            id: "prodB",
            name: "componentB",
            price: 20,
            producer: "e4",
            status: "CANCELLED"
        },
        {
            id: "prodD",
            name: "componentD",
            price: 15,
            producer: "e5"
        }
    ]
  ) {
    id
    status
    products{
      name
      price
    }
  }
}

Produces:

{"data":{"createOption":{"id":"d12ef60f-21a8-41f3-825d-5762630acdb4","status":"CANCELLED","products":[{"name":"componentB","price":20,},{"name":"componentD","price":15,}]}}}

No need to say that to get above result you need to add:

typeQuery {
    products(query: String): [Product!]!
    // others
}

typeProduct {
    id: ID!
    name: String!
    price: Float!
    producer: Company!
    status: String
}

I know it is not the best way, but I did not find a way of doing it in documentation.

Solution 3:

I ended up manually parsing the correct schema, since JavaScript Arrays and JSON.stringify strings were not accepted as graphQL schema format.

const id = 5;
const title = 'Title test';

let formattedAttachments = '';
attachments.map(attachment => {
  formattedAttachments += `{ id: ${attachment.id}, short_id: "${attachment.shortid}" }`;      
  // { id: 1, short_id: "abcxyz" }{ id: 2, short_id: "bcdqrs" }
});

// Queryconst query = `
  mutation {
    addChallengeReply(
      challengeId: ${id}, 
      title: "${title}", 
      attachments: [${formattedAttachments}]
    ) {
      id
      title
      description
    }
  }
`;

Solution 4:

What i understand by your requirement is that if you have the following code

const user = {
    name:"Rohit", 
    age:27, 
    marks: [10,15], 
    subjects:[
        {name:"maths"},
        {name:"science"}
    ]
};

const query = `mutation {
        createUser(user:${user}) {
            name
        }
}`

you must be getting something like

"mutation {
        createUser(user:[object Object]) {
            name
        }
}"

instead of the expected

"mutation {
        createUser(user:{
            name: "Rohit" ,
            age: 27 ,
            marks: [10 ,15 ] ,
            subjects: [
                {name: "maths" } ,
                {name: "science" } 
                ] 
            }) {
            name
        }
}"

If this is what you wanted to achieve, then gqlast is a nice tag function which you can use to get the expected result

Simply grab the js file from here and use it as:

const user = {
    name:"Rohit", 
    age:27, 
    marks: [10,15], 
    subjects:[
        {name:"maths"},
        {name:"science"}
    ]
};

const query = gqlast`mutation {
        createUser(user:${user}) {
            name
        }
}`

The result stored in the variable query will be :

"mutation {
        createUser(user:{
            name: "Rohit" ,
            age: 27 ,
            marks: [10 ,15 ] ,
            subjects: [
                {name: "maths" } ,
                {name: "science" } 
                ] 
            }) {
            name
        }
}"

Solution 5:

Pass them as JSON strings. That's what I do.

Post a Comment for "Graphql Mutation That Accepts An Array Of Dynamic Size And Common Scalar Types In One Request"