Akita: Compound or Composite Key / Id

Created on 29 Mar 2019  路  7Comments  路  Source: datorama/akita

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[x] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Single property for the key/id

Expected behavior

Compound or composite key

Minimal reproduction of the problem with instructions

I have a set of stores that track specialized instances of objects. They tie back to different tables in the data store, but have a common base. Their id fields are defined within their data store collections.

I have each of these different types as their own store and then another store that is a collection of all them. This is used for managing the active item. The problem arises when two items have the same primary id, but different types.

What is the motivation / use case for changing the behavior?

To model closer to how the normalized data is in the data store.

Most helpful comment

Here's an example from a related question in our Gitter channel:

@StoreConfig({
  name: 'profile-notification',
  idKey: 'fakeId'
})
export class ProfileNotificationStore extends EntityStore<ProfileNotificationState, ProfileNotification> {

  constructor() {
    super();
  }

  akitaPreAddEntity(x: Readonly<ProfileNotification>): ProfileNotification {
    return {
      ...x,
      fakeId: [x.transport_id, x.event_id].join(',')
    };
  }

}

All 7 comments

Can you provide a concrete example, please?

DB:
Consent Form

| Id | UseId | OrdinalPosition | FormName |
|---|--------|------------------|--------------|
|1|1|0|Electronic Signature|
|2|1|1|Credit Report|
|3|2|0|Electronic Signature|
|4|2|1|Credit Report|

Demographics Form

| Id | UserId | OrdinalPosition | FirstName |
|--|----------|------------------|-------------|
|1|1|2|Richard|
|2|2|2|Mike|

REST Response /forms?userId=1

[
  {
    "$type": "MyApp.ConsentForm",
    "id": 1,
    "ordinalPosition": 0,
    "userId": 1,
    "Name": "Electronic Signature"
  },
  {
    "$type": "MyApp.ConsentForm",
    "id": 2,
    "ordinalPosition": 1,
    "userId": 1,
    "Name": "Electronic Signature"
  },
  {
    "$type": "MyApp.DemographcisForm",
    "id": 1,
    "ordinalPosition": 2,
    "userId": 1,
    "Name": "Richard"
  }
]

Forms id array:

[ 1, 2, 1 ]

For this case I have three stores:

  • Forms store - { id: number, schema: string }
  • ConsentForm store - IConsentForm
  • Demographics store - IDemographics

I've created three matching queries. For the form's query I do a combineLatest with a selectAll from itself, and selectAll({ asObject: true }) from each of the other queries to build up a collection.

I'm trying to find a work-around so that the id's are unique but it would be nice to have some way where I could say the "key" was [ "id", "schema" ] and it would "pluck" those properties from the objects in the store.

And this id is relevant only for the client-side?

The id comes from the DB and is the primary key.

I just realized I do have ordinalPosition on the objects. The values aren't unique across the objects and unfortunately I can add objects dynamically so I still unsure how I'd add new objects to the stores.

If it was something like:

const keys = 
[
  { "id": 1, "schema": "MyApp.ConsentForm" },
  { "id": 2, "schema": "MyApp.ConsentForm" },
  { "id": 1, "schema": "MyApp.DemographcisForm" },
];

I could add objects with a negative id and any ordinalPosition...

And you can't set the id dynamically in the akitaPreEntitiyAdd hook?

Here's an example from a related question in our Gitter channel:

@StoreConfig({
  name: 'profile-notification',
  idKey: 'fakeId'
})
export class ProfileNotificationStore extends EntityStore<ProfileNotificationState, ProfileNotification> {

  constructor() {
    super();
  }

  akitaPreAddEntity(x: Readonly<ProfileNotification>): ProfileNotification {
    return {
      ...x,
      fakeId: [x.transport_id, x.event_id].join(',')
    };
  }

}

AH! That should work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brgrz picture brgrz  路  4Comments

amr-alamir picture amr-alamir  路  6Comments

NetanelBasal picture NetanelBasal  路  6Comments

zvnt picture zvnt  路  6Comments

mikejr83 picture mikejr83  路  6Comments