Skip to main content

UpdateAttributesCommand

Performs a UpdateAttributes Operation on an entity item. Similar to UpdateItemCommand except than deep attribute updates are non-partial:

import { UpdateAttributesCommand } from 'dynamodb-toolbox/entity/actions/updateAttributes'

const updateAttributesCommand = PokemonEntity.build(
UpdateAttributesCommand
)

const params = updateAttributesCommand.params()
await updateAttributesCommand.send()

Request​

.item(...)​

(required)

The attributes to update, including the key:

import { UpdateAttributesCommand } from 'dynamodb-toolbox/entity/actions/updateAttributes'

await PokemonEntity.build(UpdateAttributesCommand)
.item({
pokemonId: 'pikachu1',
level: 12,
...
})
.send()

You can use the UpdateAttributesInput type to explicitly type an object as a UpdateAttributesCommand item object:

import type { UpdateAttributesInput } from 'dynamodb-toolbox/entity/actions/updateAttributes'

const item: UpdateAttributesInput<typeof PokemonEntity> = {
pokemonId: 'pikachu1',
level: 12,
...
}

await PokemonEntity.build(UpdateAttributesCommand).item(item).send()

UpdateAttributesInput differs from PutItemInput as the root attributes are partially required – except for always required attributes without defaults or links – and benefit from an extended syntax that reflects the capabilities of DynamoDB.

It also differs from UpdateItemInput as deep attributes (e.g. lists, maps and records) are always completely overridden by default.

Root attributes​

Root attributes, wether flat or deep, benefit from the same syntax as the UpdateItemCommand command:

Examples
// πŸ‘‡ Extended syntax is taken from `UpdateItemCommand`
import { $remove } from 'dynamodb-toolbox/entity/actions/update'

await PokemonEntity.build(UpdateAttributesCommand)
.item({
pokemonId: 'pikachu1',
// πŸ‘‡ clear 'statusEffect' from pokemon
statusEffect: $remove()
})
.send()

Deep attributes​

In the case of deep attributes (e.g. lists, maps and records), updates are complete by default:

// πŸ‘‡ Complete overrides
await PokemonEntity.build(UpdateAttributesCommand).item({
...
// Resets list
skills: ['thunder'],
// Removes all other map attributes
some: {
deep: {
field: 'foo',
otherField: 42
}
},
// Removes all other record keys
bestSkillByType: {
electric: 'thunder'
}
})

Lists benefit from additional $append and $prepend extensions, which can use references:

import {
$append,
$prepend
} from 'dynamodb-toolbox/entity/actions/update'

PokemonEntity.build(UpdateAttributesCommand).item({
...
skills: $append(['thunder', 'dragon-tail']),
levelHistory: $append($get('level')),
types: $prepend(['flight']),
})
info

$append and $prepend are upserts: they create a new list if the attribute is missing from the item.

.options(...)​

Provides additional options:

await PokemonEntity.build(UpdateAttributesCommand)
.item(...)
.options({
returnValues: 'UPDATED_OLD',
capacity: 'TOTAL',
...
})
.send()

The options are the same as the UpdateItemCommand action options. Check the dedicated section for more details.

Response​

The data is returned using the same response syntax as the DynamoDB UpdateItem API, with an additional ToolboxItem property, which allows you to retrieve the item generated by DynamoDB-Toolbox:

const { ToolboxItem: generatedPokemon } =
await PokemonEntity.build(UpdateAttributesCommand)
.item(...)
.send()

// πŸ‘‡ Great for auto-generated attributes
const modifiedTimestamp = generatedPokemon.modified

If present, the returned attributes are formatted by the Entity.

You can use the UpdateAttributesResponse type to explicitly type an object as an UpdateAttributesCommand response object:

import type { UpdateAttributesResponse } from 'dynamodb-toolbox/entity/actions/updateAttributes'

const response: UpdateAttributesResponse<
typeof PokemonEntity,
// πŸ‘‡ Optional options
{ returnValues: 'ALL_OLD' }
// πŸ‘‡ Typed as PokemonΒ | undefined
> = { Attributes: ... }