update mutation with new cli does not work???
See original GitHub issueNote: If your issue/bug is regarding the AWS Amplify Console service, please log it in the Amplify Console GitHub Issue Tracker
Describe the bug A clear and concise description of what the bug is. Create a new project with schema. I am unable to update any of the values with generated mutation graphql mutations with cli. I make sure the required input values are included in the inputs to update the non-required values when I run my mutations but no change. I have also tried the appsync console with no avail. I have erased and tried a whole new environment in the cli but the bug keeps repeating. I am using 4.16.1. I have Merge enabled. The backend schema has
_version: Int!
_deleted: Boolean
_lastChangedAt: AWSTimestamp!
included. I also have iam provider and cognito user pools for auth rules. I am trying to update Profile table for my webapp.
here the VTL template
## [Start] Determine request authentication mode **
#if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
#set( $authMode = "userPools" )
#end
## [End] Determine request authentication mode **
## [Start] Check authMode and execute owner/group checks **
#if( $authMode == "userPools" )
## [Start] Static Group Authorization Checks **
#set($isStaticGroupAuthorized = $util.defaultIfNull(
$isStaticGroupAuthorized, false))
## Authorization rule: { allow: groups, groups: ["Users"], groupClaim: "cognito:groups" } **
#set( $userGroups = $util.defaultIfNull($ctx.identity.claims.get("cognito:groups"), []) )
#set( $allowedGroups = ["Users"] )
#foreach( $userGroup in $userGroups )
#if( $allowedGroups.contains($userGroup) )
#set( $isStaticGroupAuthorized = true )
#break
#end
#end
## [End] Static Group Authorization Checks **
#if( ! $isStaticGroupAuthorized )
## No dynamic group authorization rules **
## No owner authorization rules **
## [Start] Collect Auth Condition **
#set( $authCondition = $util.defaultIfNull($authCondition, {
"expression": "",
"expressionNames": {},
"expressionValues": {}
}) )
#set( $totalAuthExpression = "" )
## Add dynamic group auth conditions if they exist **
#if( $groupAuthExpressions )
#foreach( $authExpr in $groupAuthExpressions )
#set( $totalAuthExpression = "$totalAuthExpression $authExpr" )
#if( $foreach.hasNext )
#set( $totalAuthExpression = "$totalAuthExpression OR" )
#end
#end
#end
#if( $groupAuthExpressionNames )
$util.qr($authCondition.expressionNames.putAll($groupAuthExpressionNames))
#end
#if( $groupAuthExpressionValues )
$util.qr($authCondition.expressionValues.putAll($groupAuthExpressionValues))
#end
## Add owner auth conditions if they exist **
#if( $totalAuthExpression != "" && $ownerAuthExpressions && $ownerAuthExpressions.size() > 0 )
#set( $totalAuthExpression = "$totalAuthExpression OR" )
#end
#if( $ownerAuthExpressions )
#foreach( $authExpr in $ownerAuthExpressions )
#set( $totalAuthExpression = "$totalAuthExpression $authExpr" )
#if( $foreach.hasNext )
#set( $totalAuthExpression = "$totalAuthExpression OR" )
#end
#end
#end
#if( $ownerAuthExpressionNames )
$util.qr($authCondition.expressionNames.putAll($ownerAuthExpressionNames))
#end
#if( $ownerAuthExpressionValues )
$util.qr($authCondition.expressionValues.putAll($ownerAuthExpressionValues))
#end
## Set final expression if it has changed. **
#if( $totalAuthExpression != "" )
#if( $util.isNullOrEmpty($authCondition.expression) )
#set( $authCondition.expression = "($totalAuthExpression)" )
#else
#set( $authCondition.expression = "$authCondition.expression AND ($totalAuthExpression)" )
#end
#end
## [End] Collect Auth Condition **
#end
## [Start] Throw if unauthorized **
#if( !($isStaticGroupAuthorized == true || ($totalAuthExpression != "")) )
$util.unauthorized()
#end
## [End] Throw if unauthorized **
#end
## [End] Check authMode and execute owner/group checks **
#if( $authCondition && $authCondition.expression != "" )
#set( $condition = $authCondition )
#if( $modelObjectKey )
#foreach( $entry in $modelObjectKey.entrySet() )
$util.qr($condition.put("expression", "$condition.expression AND attribute_exists(#keyCondition$velocityCount)"))
$util.qr($condition.expressionNames.put("#keyCondition$velocityCount", "$entry.key"))
#end
#else
$util.qr($condition.put("expression", "$condition.expression AND attribute_exists(#id)"))
$util.qr($condition.expressionNames.put("#id", "id"))
#end
#else
#if( $modelObjectKey )
#set( $condition = {
"expression": "",
"expressionNames": {},
"expressionValues": {}
} )
#foreach( $entry in $modelObjectKey.entrySet() )
#if( $velocityCount == 1 )
$util.qr($condition.put("expression", "attribute_exists(#keyCondition$velocityCount)"))
#else
$util.qr($condition.put("expression", "$condition.expression AND attribute_exists(#keyCondition$velocityCount)"))
#end
$util.qr($condition.expressionNames.put("#keyCondition$velocityCount", "$entry.key"))
#end
#else
#set( $condition = {
"expression": "attribute_exists(#id)",
"expressionNames": {
"#id": "id"
},
"expressionValues": {}
} )
#end
#end
## Automatically set the updatedAt timestamp. **
$util.qr($context.args.input.put("updatedAt", $util.defaultIfNull($ctx.args.input.updatedAt, $util.time.nowISO8601())))
$util.qr($context.args.input.put("__typename", "Profile"))
## Update condition if type is @versioned **
#if( $versionedCondition )
$util.qr($condition.put("expression", "($condition.expression) AND $versionedCondition.expression"))
$util.qr($condition.expressionNames.putAll($versionedCondition.expressionNames))
$util.qr($condition.expressionValues.putAll($versionedCondition.expressionValues))
#end
#if( $context.args.condition )
#set( $conditionFilterExpressions = $util.parseJson($util.transform.toDynamoDBConditionExpression($context.args.condition)) )
$util.qr($condition.put("expression", "($condition.expression) AND $conditionFilterExpressions.expression"))
$util.qr($condition.expressionNames.putAll($conditionFilterExpressions.expressionNames))
$util.qr($condition.expressionValues.putAll($conditionFilterExpressions.expressionValues))
#end
#if( $condition.expressionValues && $condition.expressionValues.size() == 0 )
#set( $condition = {
"expression": $condition.expression,
"expressionNames": $condition.expressionNames
} )
#end
#set( $expNames = {} )
#set( $expValues = {} )
#set( $expSet = {} )
#set( $expAdd = {} )
#set( $expRemove = [] )
#if( $modelObjectKey )
#set( $keyFields = [] )
#foreach( $entry in $modelObjectKey.entrySet() )
$util.qr($keyFields.add("$entry.key"))
#end
#else
#set( $keyFields = ["id", "_version", "_deleted", "_lastChangedAt"] )
#end
#foreach( $entry in $util.map.copyAndRemoveAllKeys($context.args.input, $keyFields).entrySet() )
#if( !$util.isNull($dynamodbNameOverrideMap) && $dynamodbNameOverrideMap.containsKey("$entry.key") )
#set( $entryKeyAttributeName = $dynamodbNameOverrideMap.get("$entry.key") )
#else
#set( $entryKeyAttributeName = $entry.key )
#end
#if( $util.isNull($entry.value) )
#set( $discard = $expRemove.add("#$entryKeyAttributeName") )
$util.qr($expNames.put("#$entryKeyAttributeName", "$entry.key"))
#else
$util.qr($expSet.put("#$entryKeyAttributeName", ":$entryKeyAttributeName"))
$util.qr($expNames.put("#$entryKeyAttributeName", "$entry.key"))
$util.qr($expValues.put(":$entryKeyAttributeName", $util.dynamodb.toDynamoDB($entry.value)))
#end
#end
#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
#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
#if( !$expRemove.isEmpty() )
#set( $expression = "$expression REMOVE" )
#foreach( $entry in $expRemove )
#set( $expression = "$expression $entry" )
#if( $foreach.hasNext() )
#set( $expression = "$expression," )
#end
#end
#end
#set( $update = {} )
$util.qr($update.put("expression", "$expression"))
#if( !$expNames.isEmpty() )
$util.qr($update.put("expressionNames", $expNames))
#end
#if( !$expValues.isEmpty() )
$util.qr($update.put("expressionValues", $expValues))
#end
{
"version": "2018-05-29",
"operation": "UpdateItem",
"key": #if( $modelObjectKey ) $util.toJson($modelObjectKey) #else {
"id": {
"S": $util.toJson($context.args.input.id)
}
} #end,
"update": $util.toJson($update),
"condition": $util.toJson($condition),
"_version": $util.defaultIfNull($ctx.args.input["_version"], "0")
}
here’s schema for table
type Profile
@model
@auth(rules: [
{ allow: public, provider: iam, operations: [read] },
{allow: groups, groups: ["public"], operations: [read]},
{allow: groups, groups: ["Users"]},
])
{
id: ID!
userId: ID!
name: String!
aboutMe: String
profilePicture: String
following: [UserHost] @connection(keyName: "byUser", fields: ["id"])
followingCount: String
user: User @connection(fields: ["userId"])
stats: Stats @connection(fields: ["userId"])
}
here’s my react code:
const updateUserProfileForm = async (values) => {
try {
const {
files,
aboutMe,
} = values;
// upload picture
const filteredFiles = files.filter(file => file !== null);
console.log(values, ' this is the values object');
console.log(files, ' this is files');
if (filteredFiles
&& filteredFiles[0]
&& filteredFiles[0].name) await uploadPicture(filteredFiles[0]);
const params = (filteredFiles && filteredFiles[0] && filteredFiles[0].name)
? {
input: {
id: profileId,
aboutMe,
profilePicture: `${credId}/${profileId}/${escapeUnsafe(filteredFiles[0].name)}`,
userId: userProfile.userId,
name: userProfile.name,
},
}
: {
input: {
id: profileId,
aboutMe,
userId: userProfile.userId,
name: userProfile.name,
},
};
const userProfileData = await API
.graphql(
graphqlOperation(
UpdateUserProfile, params,
),
);
const { data: { updateProfile: newUserProfile } } = userProfileData;
setUserProfile(newUserProfile);
console.log(newUserProfile, ' this is NewUserProfile');
setSuccess({
header: 'Update successful!',
content: 'Profile updated successfully.',
});
setError(null);
} catch (e) {
setSuccess(null);
setError({
header: 'Oops...something went wrong',
content: 'Something went wrong with updating profile, please try again.',
});
}
};
Amplify CLI Version
You can use amplify -v
to check the amplify cli version on your system
4.16.1
To Reproduce
Steps to reproduce the behavior or terminal output if applicable
- create new schema
- create values inside dynamodb table using appsync
- use update mutation while including the required fields.
Expected behavior A clear and concise description of what you expected to happen. The values should update.
Screenshots If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
- OS: [e.g. Mac/Windows/Ubuntu]
- Node Version. You can use
node -v
to check the node version on your system
v12.13.1
Additional context Add any other context about the problem here.
Issue Analytics
- State:
- Created 4 years ago
- Comments:24 (5 by maintainers)
tl;dr: When you call the “updateProfile” mutation, because you have versioning turned on, you need to pass in the current _version number as part of the update input object. In your react code I can see you aren’t doing this.
To test this and show it working properly:
navigate to AppSync in your region, https://eu-west-2.console.aws.amazon.com/appsync/ . Select queries on left hand side. Login, use AppClientIDWeb from step 2.
execute the following mutations
This issue has been automatically locked since there hasn’t been any recent activity after it was closed. Please open a new issue for related bugs.
Looking for a help forum? We recommend joining the Amplify Community Discord server
*-help
channels for those types of questions.