aws-appsyncvtlaws-appsync-resolver

Appsync VTL resolvers assigning null to a an object


I extended the default resolvers I received from Amplify/Appsync for one of my models.

I saved my code as Mutation.updateMovement.preUpdate.1.req.vtl, and here's my VTL file:

#set( $muscleGroups = $ctx.args.input.muscleGroups )
#if( $muscleGroups && $muscleGroups.size() > 0 )
  #set( $primaryMuscleGroup = $muscleGroups[0] )
  $util.qr($ctx.args.input.put("primaryMuscleGroup", $primaryMuscleGroup))
#else 
  #set( $primaryMuscleGroup = null )
  $util.qr($ctx.args.input.put("primaryMuscleGroup", $primaryMuscleGroup))
#end
$util.toJson({})

This code should basically check assign the first value of the muscleGroups array to be a primary, if there is this value, and otherwise it should assign it to null.

When trying to run this, the error I received is:

"message": "Encountered \"null\" at velocity[line 6, column 46]
Was expecting one of:\n    \"[\" ...\n    \"{\" ...\n    \"(\" ...\n
<WHITESPACE> ...\n    <STRING_LITERAL> ...\n    \"true\" ...\n    \"false\" ...\n
<INTEGER_LITERAL> ...\n    <FLOATING_POINT_LITERAL> ...\n    
<IDENTIFIER> ...\n    \"{\" ...\n    <WHITESPACE> ...\n    "

I also tried the following

#set( $ctx.args.input.primaryMuscleGroup = null ) # gave the same error
#set( $ctx.args.input.primaryMuscleGroup = !null ) # gave the same error
#set( $ctx.args.input.primaryMuscleGroup =  $util.parseJson("null")) # gave error "Can't serialize value: Invalid input for Enum 'MuscleGroup'."

Later in the pipeline, in a function named Mutation.updateMovement.req.vtl,which is autogenerated by Amplify, there are checks for null, for example: #if( $util.isNull($entry.value) ) so it seems like there has to be a way to assign value to object.

I also tried some workaround to assign empty value like "" or $util.dynamodb.toNull() but this won't do, the null assigning created a remove expression under the hood which I require for my object.

Is there a proper way to assign null to an object property in VTL?


Solution

  • I figured out a way to do what I wanted, here it is:

    #set( $muscleGroups = $ctx.args.input.muscleGroups )
    
    #if(!$util.isNull($muscleGroups) && $muscleGroups.size() > 0 )
      #set( $primaryMuscleGroup = $muscleGroups[0] )
      $util.qr($ctx.args.input.put("primaryMuscleGroup", $primaryMuscleGroup))
    #else
      $util.qr($ctx.args.input.put("primaryMuscleGroup", null))
    #end
    $util.toJson({})
    

    As for why, it seems like for some reason, null assignment to a variable in VTL is not supported at least not on AWS. I tried to run this VTL:

    #set( $primaryMuscleGroup = null )
    

    And still got the error from the question. So it seems to not be allowed independently of my code. Maybe later comments and experiments by me or other users will explain why this is not allowed, but for now I got my answer.