Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update graphql context in a mutation for the output object of the same mutation

I want to use a single mutation for the application to send user info to server and then get the top level query in the output. (I know this is not a good convention but I want to do this to test if I can improve performance).

So as a result, there will only be one mutation that takes user's info and returns the feed. This mutation updates the information about the user that is fetched in every query as the context of request. The context is used to generate personalized feed. However when I call this mutation, the output returned is calculated using old context. What I need to do is update the context for this same mutation too.

I put down a simplified version of the code to show what's happening:



const UserType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    someData: {
      type: GraphQLList(Post),
      resolve: (user, args, context) => getFeed(context) // context in here is the old context.
    },
  })
})

const someMutation = mutationWithClientMutationId({
  name: 'someMutation',
  inputFields: {
    location: { type: GraphQLString },
  },
  outputFields: {
    user: {
      type: UserType,
      resolve: (source, args, context) => getUser(context.location),
    },
  },
  mutateAndGetPayload: async (data, context) => {

    updateUserInfo(data)
    // I have tried updating context like this but it's not working.
    context = { location: data.location }

    return {
        // I even tried putting user here like this:
        // user: getUser(data.location)
        // However, the resulting query fails when running getFeed(context)
        // the context is still the old context
    }
  },
})
like image 954
Mo Ganji Avatar asked Jul 14 '18 07:07

Mo Ganji


1 Answers

This is just how JavaScript works. You can reassign the value of a function parameter, but that will not change the value the function was passed.

function makeTrue (value) {
  value = true
  console.log(value) // true
}

var myVariable = false
makeTrue(myVariable)
console.log(myVariable) // false

If the value you pass to the function is an object or an array, you can mutate it and the original value will be mutated as well because objects and arrays in Javascript are passed by reference.

function makeItTrue (value) {
  value.it = true
  console.log(value.it) // true
}

var myVariable = { it: false }
makeTrue(myVariable)
console.log(myVariable.it) // true

In other words, you need to mutate the context parameter instead of reassigning it.

like image 123
Daniel Rearden Avatar answered Oct 26 '22 08:10

Daniel Rearden