I'd like to add a string word to the listOfVideosRated[]
list in my Users table.
If you can post your schema / resolver mapping template I can offer more specific advice, but I'll do my best to answer this with what you've posted so far.
If you have the existing item already, one way to do this would be to update the existing Pairs and pass that to your existing mutation.
const existingItem = {
id: "e5eb02ae-04d5-4331-91e6-11efaaf12ea5",
Pairs: [['a', 'b'],['c', 'd'],['e', 'f']]
}
const newPairs = {
number1: "g",
number2: "h"
}
const updateinfo = {
id: existingItem.id,
// Note that if existingItem.Pairs is always defined this can be simplified to
// Pairs: [...existingItem.Pairs, [newPairs.number1, newPairs.number2]]
Pairs: existingItem.Pairs ?
[...existingItem.Pairs, [newPairs.number1, newPairs.number2]] :
[[newPairs.number1, newPairs.number2]]
}
try {
await API.graphql(graphqlOperation (UpdateInfo, { input: updateinfo }))
//mutation
console.log('success')
}
catch (err) {
console.log(err)
}
If you do not have the existing item or if Pairs
can be pretty big, AWS DynamoDB's list_append
function can be used instead.
list_append (operand, operand)
This function evaluates to a list with a new element added to it. You can append the new element to the start or the end of the list by reversing the order of the operands.
Here is an example with a specific mutation that uses it.
### SDL
type Item {
id: ID!
Pairs: [[String]]
}
input AddPairInput {
id: ID!
number1: String!
number2: String!
}
type Mutation {
addPairToItem(input: AddPairInput!): Item!
}
...rest of schema omitted for brevity
### Resolver Request Mapping Template
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
### Note: we also use if_not_exists here so this works if Pairs is not yet defined on the item.
"expression":"SET Pairs = list_append(if_not_exists(Pairs, :emptyList), :newPair)",
"expressionValues":
{
":newPair":{"L": [{"L":[{"S":"$ctx.args.input.number1"},
{"S":"$ctx.args.input.number2"}]}]},
":emptyList":{"L": []}
}
}
}
### Resolver Response Mapping Template
$util.toJson($ctx.result)
This way is also nice because if someone else updates Pairs, you won't overwrite their update. You can also add the new Pair to the beginning of the list by inverting the order of your arguments to the list_append
function.
If your project was generated by AWS Amplify, you will need to add a customer resolver.
### ./amplify/backend/api/<api_name>/schema.graphql
type Item @model {
id: ID!
Pairs: [[String]]
}
type Mutation {
addPairToItem(input: AddPairToItemInput!): Item!
}
input AddPairToItemInput {
id: ID!
number1: String!
number2: String!
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addPairToItem.req.vtl
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
"expression":"SET Pairs = list_append(if_not_exists(Pairs, :emptyList), :newPair)",
"expressionValues":
{
":newPair":{"L": [{"L":[{"S":"$ctx.args.input.number1"},{"S":"$ctx.args.input.number2"}]}]},
":emptyList":{"L": []}
}
}
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addPairToItem.res.vtl
$util.toJson($ctx.result)
### ./amplify/backend/api/<api_name>/stacks/CustomResources.json
"Resources": {
// ...other resources may exist here
"AddPairToItemResolver": {
"Type": "AWS::AppSync::Resolver",
"Properties": {
"ApiId": {
"Ref": "AppSyncApiId"
},
"DataSourceName": "ItemTable",
"TypeName": "Mutation",
"FieldName": "addPairToItem",
"RequestMappingTemplateS3Location": {
"Fn::Sub": [
"s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Mutation.addPairToItem.req.vtl",
{
"S3DeploymentBucket": {
"Ref": "S3DeploymentBucket"
},
"S3DeploymentRootKey": {
"Ref": "S3DeploymentRootKey"
}
}
]
},
"ResponseMappingTemplateS3Location": {
"Fn::Sub": [
"s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Mutation.addPairToItem.res.vtl",
{
"S3DeploymentBucket": {
"Ref": "S3DeploymentBucket"
},
"S3DeploymentRootKey": {
"Ref": "S3DeploymentRootKey"
}
}
]
}
}
}
},
amplify api gql-compile
to see the new changes in your generated code (optional).amplify push
to deploy your changes.Now you can either run amplify api console
or use the new generated code to test the changes with your new mutation.
To generate the new code you can run amplify codegen
. You should then be able to do something like this
import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as mutations from './graphql/mutations';
// Mutation
const addPairToItem = {
id: '1',
number1: 'a',
number2: 'b'
};
const newItem = await API.graphql(graphqlOperation(mutations.addPairToItem, {input: addPairToItem}));
Remember to update your CustomResources.json file with any new resolvers you add.
### ./amplify/backend/api/<api_name>/schema.graphql
type Item @model {
id: ID!
words: [String]
}
input AddWordInput {
id: ID!
word: String!
}
type Mutation {
addWordToItem(input: AddWordInput!): Item!
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordToItem.req.vtl
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
"expression":"SET words = list_append(if_not_exists(words, :emptyList), :newWord)",
"expressionValues":
{
":newWord":{"L": [{"S":"$ctx.args.input.word"}]},
":emptyList":{"L": []}
}
}
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordToItem.res.vtl
$util.toJson($ctx.result)
### Usage
import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as mutations from './graphql/mutations';
// Mutation
const newWord = {
id: '1',
word: 'foo'
};
const newItem = await API.graphql(graphqlOperation(mutations.addWordToItem, {input: newWord}));
Note: I am introducing $util.dynamodb.toDynamoDBJson
here to make constructing our VTL easier. I've been explicit thus far but this utility can simplify a lot of the work. More here
### ./amplify/backend/api/<api_name>/schema.graphql
type Item @model {
id: ID!
words: [String]
}
input AddWordsInput {
id: ID!
words: [String!]!
}
type Mutation {
addWordsToItem(input: AddWordsInput!): Item!
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordsToItem.req.vtl
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
"expression":"SET words = list_append(if_not_exists(words, :emptyList), :newWords)",
"expressionValues":
{
":newWords": $util.dynamodb.toDynamoDBJson($ctx.args.input.words),
":emptyList": $util.dynamodb.toDynamoDBJson([])
}
}
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordsToItem.res.vtl
$util.toJson($ctx.result)
### Usage
import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as mutations from './graphql/mutations';
// Mutation
const newWords = {
id: '1',
words: ["bar","xyz","bar"]
};
const newItem = await API.graphql(graphqlOperation(mutations.addWordsToItem, {input: newWords}));
Removing elements from lists in DynamoDB is done using the REMOVE action. You must specify a non-negative index as part of the update expression. If the index does not exist on the item, your request will not fail (e.g. no index out of bounds exceptions).
type Item @model {
id: ID!
words: [String]
}
input RemoveWordInput {
id: ID!
wordIndex: Int!
}
type Mutation {
removeWordFromItem(input: RemoveWordInput!): Item!
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.removeWordFromItem.req.vtl
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"id": { "S": "$ctx.args.input.id"}
},
"update": {
"expression":"REMOVE words[$ctx.args.input.wordIndex]"
}
}
### ./amplify/backend/api/<api_name>/resolvers/Mutation.removeWordFromItem.res.vtl
$util.toJson($ctx.result)
### Usage
import Amplify, { API, graphqlOperation } from "aws-amplify";
import * as mutations from './graphql/mutations';
// Mutation
const removeWord = {
id: '1',
// The index is 0 based so wordIndex: 0
// would delete the first item,
// wordIndex: 1 deletes the second, etc.
wordIndex: 1
};
const newItem = await API.graphql(graphqlOperation(mutations.removeWordFromItem, {input: removeWord}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With