How to replace a list in a mutation using Dgraph Cloud

I am using the pre-built mutations and finding the set part of the mutation isn’t doing what I would expect it to.

For example I have the mutation:

  mutation EditEntryMutation(
    $title: String!
    $genres: [Genre]
  ) {
    updateEntry(
      input: {
        filter: { title: { eq: $title } }
        set: {
          genres: $genres
        }
      }
    ) {
      entry {
        genres
      }
    }
  }

I would expect that this operation replaces the list of genres with the new list, however it appends whatever values missing.

For example:

In my database I have the values genres: ["action", "drama"].

  • If I run this mutation with the values ["action", "drama", "adventure"], the database will now have the values ["action", "drama", "adventure"].
  • If I run this mutation with the values ["action"], the database will continue to have the values ["action", "drama"].
  • If I run this mutation with the values ["romance", "fantasy"], the database will now have the values ["action", "drama", "romance", "fantasy"].
  • If I run this mutation with and empty array [], the database will continue to have the values ["action", "drama"].

How can I do a mutation where it replaces the values rather then appending?

1 Like

First do a get query for that respective array, then do a mutation somewhat as follows →

mutation MyMutation($array: [Int!]!, $array1: [Int!]! ) {
  updatearrayStore(input: {filter: {name: {eq: "anArray"}}, set: {array: $array}, remove: {array: $array1}}) {
    arrayStore {
      array
      name
    }
  }
}

I am not sure I follow… are you able to change my mutation in my example to achieve this goal? For more context I have a form where a user can edit a list of values. It would be a lot of additional code to have to work out which values were removed and run a separate mutation just for this. There is also a number of lists in this form, hence why I am looking to do everything in one mutation.

Is there no way to have this mutation to a simple replace?

Is this what you mean?

mutation EditEntryMutation(
    $title: String!
    $genresToAdd: [Genre]
    $genresToRemove: [Genre]
  ) {
    updateEntry(
      input: {
        filter: { title: { eq: $title } }
        set: {
          genres: $genresToAdd
        }
        remove {
          genres: $genresToRemove
        }
      }
    ) {
      entry {
        genres
      }
    }
  }

This does work however feels like this is something the mutation should handle. Is there another mutation property I should be using instead for a simple replace?

1 Like

Yep, this will work for now. I think a ticket should be created for allowing creating a new array instead of setting values to an existing array. @hardik can look into this and see where it can fit in the roadmap

1 Like

Here is an alternative method which involves two mutation blocks inside a single mutation operation:

mutation EditEntryMutation(
    $title: String!
    $genres: [Genre]
  ) {
    clean: updateEntry(input: {
      filter: { title: { eq: $title } }
      remove: {
        genres: null # removes all edges
      }
    }) { numUid }
    updateEntry(
      input: {
        filter: { title: { eq: $title } }
        set: {
          genres: $genres
        }
      }
    ) {
      entry {
        genres
      }
    }
  }
1 Like

Are there any updates on this? I have found an awkward situation I have run into a few times.

It is when I am wanting to remove/update a nested array in my type. I am wanting to pass in an array of IDs, but instead I have to pass in an array of TypeRef, which implies I have to have all the data for that type.

Is there a way around this? The below is what I need to pass in at the moment.

 mutation EditEntryMutation(
    $myKey: String
    $seoKeywordsToAdd: [KeywordRef!]
    $seoKeywordsToRemove: [KeywordRef!]
  ) {
    updateEntry(
      input: {
        filter: { myKey: { eq: $myKey } }
        set: {
          seo: { keywords: $seoKeywordsToAdd }
        }
        remove: {
          seo: { keywords: $seoKeywordsToRemove }
        }
      }
    ) {
      entry {
        urlKey
      }
    }
  }

But this is what I would like to pass in:

 mutation EditEntryMutation(
    $myKey: String
    $seoKeywordsToAdd: [ID!]
    $seoKeywordsToRemove: [ID!]
  ) {
    updateEntry(
      input: {
        filter: { myKey: { eq: $myKey } }
        set: {
          seo: { keywords: $seoKeywordsToAdd }
        }
        remove: {
          seo: { keywords: $seoKeywordsToRemove }
        }
      }
    ) {
      entry {
        urlKey
      }
    }
  }