Reputation: 1518
Preface: I'm new to GraphQL and Amplify.
I have a user object that contains two arrays, one called preferred_genres
, and another called preferred_characters
. I have a profile page where the user can edit their profile and add items to these arrays.
The update mutation provided by AWS Amplify seems only to be adding elements to the array, never removing them. If on my UI I remove an item from the list and then submit the update mutation, the item is not removed from my backend. If I add an item to the array, the item is added on the backend, but I also end up with duplicate values for those already in the backend.
What I'm trying to do is overwrite the array on the backend with the data I'm submitting from the front end. Am I missing something obvious? Is there a more appropriate way of achieving this in GraphQL?
type User @model {
id: ID!
...
preferred_characters: [Character]
preferred_genres: [Genre]
...
}
Upvotes: 3
Views: 3159
Reputation: 6751
amplify/backend/api/<yourApi>/transform.conf.json
From:
To:
Upvotes: 3
Reputation: 1518
I stumbled upon this question in the Amplify GitHub issues about the AWSJSON scalar having a similar issue. The issue seems to be related to conflict resolution in the API.
I don't remember setting that up, but I tried amplify update API
, chose my GraphQL API and the advanced options, declined any conflict resolution and ran amplify push
.
Now values are saving as expected. When I remove an item from an array it's removed from the backend and visa-versa.
Upvotes: 0
Reputation: 2279
A way to implement this would be to change your updateUser resolver to update or create these entries.
{
"version" : "2017-02-28",
"operation" : "UpdateItem",
"key" : {
"id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
},
## Set up some space to keep track of things you're updating **
#set( $expNames = {} )
#set( $expValues = {} )
#set( $expSet = {} )
#set( $expAdd = {} )
#set( $expRemove = [] )
## Increment "version" by 1 **
$!{expAdd.put("version", ":one")}
$!{expValues.put(":one", { "N" : 1 })}
## Iterate through each argument, skipping "id" and "expectedVersion" **
#foreach( $entry in $context.arguments.entrySet() )
#if( $entry.key != "id" && $entry.key != "expectedVersion" )
#if( (!$entry.value) && ("$!{entry.value}" == "") )
## If the argument is set to "null", then remove that attribute from the item in DynamoDB **
#set( $discard = ${expRemove.add("#${entry.key}")} )
$!{expNames.put("#${entry.key}", "$entry.key")}
#else
## Otherwise set (or update) the attribute on the item in DynamoDB **
$!{expSet.put("#${entry.key}", ":${entry.key}")}
$!{expNames.put("#${entry.key}", "$entry.key")}
$!{expValues.put(":${entry.key}", { "S" : "${entry.value}" })}
#end
#end
#end
## Start building the update expression, starting with attributes you're going to SET **
#set( $expression = "" )
#if( !${expSet.isEmpty()} )
#set( $expression = "SET" )
#foreach( $entry in $expSet.entrySet() )
#set( $expression = "${expression} ${entry.key} = ${entry.value}" )
#if ( $foreach.hasNext )
#set( $expression = "${expression}," )
#end
#end
#end
## Continue building the update expression, adding attributes you're going to ADD **
#if( !${expAdd.isEmpty()} )
#set( $expression = "${expression} ADD" )
#foreach( $entry in $expAdd.entrySet() )
#set( $expression = "${expression} ${entry.key} ${entry.value}" )
#if ( $foreach.hasNext )
#set( $expression = "${expression}," )
#end
#end
#end
## Continue building the update expression, adding attributes you're going to REMOVE **
#if( !${expRemove.isEmpty()} )
#set( $expression = "${expression} REMOVE" )
#foreach( $entry in $expRemove )
#set( $expression = "${expression} ${entry}" )
#if ( $foreach.hasNext )
#set( $expression = "${expression}," )
#end
#end
#end
## Finally, write the update expression into the document, along with any expressionNames and expressionValues **
"update" : {
"expression" : "${expression}"
#if( !${expNames.isEmpty()} )
,"expressionNames" : $utils.toJson($expNames)
#end
#if( !${expValues.isEmpty()} )
,"expressionValues" : $utils.toJson($expValues)
#end
},
"condition" : {
"expression" : "version = :expectedVersion",
"expressionValues" : {
":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion)
}
}
}
Upvotes: 2