Skip to content

Read operations return undefined for setter-only watch attributes that aren't stored on the item #578

Description

@anatolzak

A watch attribute that only has a set (e.g. an updatedAt timestamp) shows up as undefined on reads when it isn't stored on the item.

The fix is to treat watchers per method: only run a watcher on get if it defines a get, and on set if it defines a set.

Version: 3.9.0

Model

{
  model: { entity: "watcherItem", service: "Playground", version: "1" },
  attributes: {
    id: { type: "string", required: true },
    name: { type: "string", required: true },
    updatedAt: { type: "number", watch: "*", set: () => Date.now() },
  },
  indexes: {
    byId: {
      pk: { field: "pk", composite: ["id"] },
      sk: { field: "sk", composite: ["id"] },
    },
  },
}

Repro

const result = entity.parse({
  Item: {
    pk: "$playground#id_123",
    sk: "$watcheritem_1#id_123",
    id: "123",
    name: "test", // updatedAt not stored
  },
});

"updatedAt" in result.data; // true, expected false
Object.keys(result.data);   // ['id', 'name', 'updatedAt']

Same thing happens on .get().go() for items missing the value (e.g. records written before the watcher existed). A projection that excludes the attribute hides it, since the key gets filtered out afterward.

Expected

updatedAt shouldn't appear at all when it's not stored and has no getter. Watchers with a getter should still run on reads, and setter watchers should still generate on writes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions