tywalch/electrodb

Remove an element from an attribute of type list

RaeesBhatti opened this issue · 4 comments

Describe the bug
Unable to remove a specific item from a list property/attribute using ElectroDb

ElectroDB Version
2.3.5

ElectroDB Playground Link
Link

Entity/Service Definitions
Include your entity model (or a model that sufficiently recreates your issue) to help troubleshoot.

const trackers = new Entity(
  {
    model: {
      entity: "tracker",
      version: "1",
      service: "trackerapp"
    },
    attributes: {
      gameId: {
        type: "string",
        required: true
      },
      subscribers: {
        type: 'list',
        required: true,
        items: {
          type: 'map',
          required: true,
          properties: {
            emailAddress: { type: 'string', required: true },
            thresholdPrice: { type: 'number', required: true },
          },
        },
      },
      createdAt: {
        type: "number",
        default: () => Date.now(),
        // cannot be modified after created
        readOnly: true
      },
      updatedAt: {
        type: "number",
        // watch for changes to any attribute
        watch: "*",
        // set current timestamp when updated
        set: () => Date.now(),
        readOnly: true
      }
    },
    indexes: {
      games: {
        pk: { field: "pk", composite: ["gameId"] },
        sk: { field: "sk", composite: [] }
      }
    }
  },
  { table }
);

Expected behavior
An ability to remove a specific element from tracker.subscribers list. DynamoDb's documentation on Removing Items from a List.

Errors
I've tried to do it with .remove method on .patch but that just takes a string/property name and complains that

Attribute "subscribers" is Required and cannot be removed

For more detail on this error reference https://electrodb.dev/en/reference/errors/#invalid-attribute

I've also tried the following

.data((attr, op) => `${op.remove(attr.subscribers)}[2]`)

but that throws the same error.

The other way I've tried is just manually entering the query in .data like so .data((attr, op) => 'REMOVE subscribers[2]') but the operation string gets dropped and doesn't end up executing.

Additional context

Hi @RaeesBhatti 👋

It looks like you set the items to that list to "required" which creates a constraint to enforce that the property is provided on creation and that it won't be deleted. If you remove "required" from the list item you'll be able to delete individual items

Thanks for the quick reply @tywalch . And thank you for creating this project!

After I'd removed the required prop from the list items, I tried to do .data((attr, op) => op.remove(attr.subscribers, 2)) but the second argument is ignored. It throws an error:

Attribute \"subscribers\" is Required and cannot be removed

Can you please give me a hint towards the right approach!

Ah I see. Seems obvious in retrospect 😅. Thank you!