briebug / ngrx-auto-entity

NgRx Auto-Entity: Simplifying Reactive State
https://briebug.gitbook.io/ngrx-auto-entity/
Other
66 stars 12 forks source link

Feature: Support nest @Key decorators #96

Open schuchard opened 4 years ago

schuchard commented 4 years ago

Sometimes the unique identifier is not at the root of an entity. Adding support for nested decoration would be nice.


class Order {
    name: 'Food Order'
    metadata: {
        @Key id: 12345, 
    }
}
jrista commented 4 years ago

I looked into this more. I'm not sure our original idea of simply decorating a nested property with @Key is going to work. There is no standardized way to get the parent object of an object in JS. There are ways to get the parent prototype, but for most arbitrary objects, even nested ones, that will be Object.prototype and not the parent object instance.

I think the only way to support more complex and arbitrary keys, is going to be through the @Entity decorator. Something like:

@Entity({
    modelName: 'Order',
    key: 'metadata.id'
})
class Order {
    name: 'Food Order',
    metadata: {
        id: 12345
    }
}

We could also support an array of strings for simple composite keys, as well as a function, allowing very flexible and powerful key generation. For backwards compatibility of course, the current @Key decorator would remain in tact as it currently works, but the key property of @Entity would be an alternative way of configuring the key for entities.

jrista commented 4 years ago

Composite key with array notation:

@Entity({
    modelName: 'Order',
    key: ['purchaseOrderNo', 'metadata.id']
})
class Order {
    purchaseOrderNo: 'FO_C1',
    name: 'Food Order',
    metadata: {
        id: 12345
    }
}

Functional option:

@Entity({
    modelName: 'Order',
    key: order => order.metadata.id
})
class Order {
    name: 'Food Order',
    metadata: {
        id: 12345
    }
}
schuchard commented 4 years ago

i like both of those options

jrista commented 2 years ago

After some contemplation, I think I am going to go with only the functional option, to keep things simple and consistent:

@Entity({
    modelName: 'Order',
    key: order => order.metadata.id
})
class Order {
    name: 'Food Order',
    metadata: {
        id: 12345
    }
}
jrista commented 2 years ago

This will be the final feature for NgRx Auto-Entity before its final v12 (to align with Angular v12 back to v9) release. This feature will touch a number of key locations in the code, so I'll release it as a beta initially, but once this feature is done final work can begin on converting the library over to use angular 13 and up (which switches to RxJs v7).

jrista commented 2 years ago

Looks like this change will have to be fairly extensive, and most likely breaking. For now, I'm going to shelve this issue. Will address at a later date, as being able to specify a custom key retrieval function would be very useful.