Akita: [Discussion] Multiple active entity

Created on 3 Jan 2019  路  15Comments  路  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

Active entity is unique !

Expected behavior

I don't know if its something you would be interested of but in my case, if I could be able to set multiple active entity, it would be helpful !!

setActive(idOrOptions: ActiveEntity | ActiveEntity[] |SetActiveOptions)
OR to avoid conflict
setActive(idOrOptions: ActiveEntity | SetActiveOptions)
setActives(idOrOptions: ActiveEntity[])

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

For example, in a dashboard page, I would like to be able to display the details of multiple entity selected.

I know it can be in conflict with the pagination plugin but the list of active entity could be the list of entity for a specific page...

In progress enhancement

Most helpful comment

Update: I have almost finished this feature and Akita still support the current API with multi-active functionality. It still needs tests, but it seems to work fine. Here is the API:

import { EntityState, EntityStore, StoreConfig, MultiActive } from '@datorama/akita';

export interface WidgetsState extends EntityState<Widget>, MultiActive {
}

const initialState = { active: [] }

@StoreConfig({ name: 'widgets' })
export class WidgetsStore extends EntityStore<WidgetsState, Widget> {
  constructor() {
    super(initialState);
  }
}

Store -

setActive([1, 2, 3]) <=== (still the same)
addActive(id | ids[])
removeActive(id | ids[])
toggleActive(id | ids[])
updateActive()

Query - (still the same API but support multi)

selectActive() : Observable<Entity[]>;
selectActiveIds() : Observable<ID[]>;
getActive(): Entity[];
getActiveId() : ID[];

All 15 comments

Actually, this is something I wanted to add a long time ago; I need to think about the implementation.

Yes, I have thinkind also about it.

Maybe keep the active feature, and add selected, that managed selected items. And then it could be great after to update/remove all selected entities.
setSelected(idOrOptions: ActiveEntity | ActiveEntity[] |SetActiveOptions); unSelect(idOrOptions: ActiveEntity | ActiveEntity[] |SetActiveOptions); updateSelected(Partial<Entity> UpdateEntity); deleteSelected(Partial<Entity> UpdateEntity);

I prefer not to bloat the API and try using setActive and selectActive.

After reexamining the feature, it couldn't use the existing methods as it should provide more functionality, for example:

Store -

setActives([1, 2, 3]) - reset the actives to the provided value.
addActive(id | ids[]) - add if not exist.
removeActive(id | ids[]) - remove if exist.
toggleActive(id | ids[]) - add/remove.

Query -

selectActives() : Observable<Entity[]>;
selectActivesIds() : Observable<ID[]>;
getActives(): Entity[];
getActivesIds() : ID[];

What do u think? I also think if this should be a part of the API or as a plugin/mixin.

What do u think? I also think if this should be a part of the API or as a plugin/mixin.

I'd make it part of the API rather than putting it into a plugin because the use case is common enough that it should be part ot the normal API.

Yes, but from the other side, it will make the core Akita bigger so I don't know. Let's put it on Gitter.

After reexamining the feature, it couldn't use the existing methods as it should provide more functionality, for example:

Store -

setActives([1, 2, 3]) - reset the actives to the provided value.
addActive(id | ids[]) - add if not exist.
removeActive(id | ids[]) - remove if exist.
toggleActive(id | ids[]) - add/remove.

Query -

selectActives() : Observable<Entity[]>;
selectActivesIds() : Observable<ID[]>;
getActives(): Entity[];
getActivesIds() : ID[];

What do u think? I also think if this should be a part of the API or as a plugin/mixin.

And, you will keep the only one active functionnality ? I thinks both can be usefull.

Sure

But why keep the same names with juste plurals. It could be confusing between two functionnality ?

  • Maybe start with a new feature setActives. I think it will be easier to maintain setActive AND setActives because they will not provide the same features at the beginning. I mean for example, the new feature with options next, previous will not work with setActives (or maybe later) and it will be easier to maintain 2 functions than multiple if in your code depending of the parameters...later you will see if you can merge. At least setActive(id) could call setActives([id])
  • If setActive is part of the core, then setActives should work in the same way ! Or put the feature
    setActive in a plugin too ;)

This is maybe not the good place but I think you should try to put as much as possible stuff in plugins. But I don't know why you don't manage plugin like the entity ?
I mean managing entity features today needs to extends specific classes (StoreEntity, QueryEntity, etc...) then we can use selectAll etc... For state history or pagination, we need to use the plugin in each component...I would prefer to add a functionality/plugin to a store or a query instead of injecting a query to a plugin...what do you think ? Then entities, active, loading could be plugins....?

I think that what you suggest is Mixins? something like:

export const TodosStore = withPagination(withStateHistory(store));

@NetanelBasal yes, I didn't really think yet about the implementation but its just composition....maybe with decorators ! :D

I just love your implementation of redux because it contains already a lot of stuff that I made with ngrx but I created a lot of adapters to manage that. It was exactly what you propose here withSomething and for each adapter, I also provided a list of selectors. Maybe there is a better/cleaner way to do this.

My main point is, keeping consistency in your lib when you want to add new feature. For me the core is only definition of store, query, etc.. Entity is already a feature !

The problem with decorators is the types.

Entity is already a feature!

We can argue on that. I can't see one application that doesn't need it. Actually, it's what makes Akita powerful IMO.

Update: I have almost finished this feature and Akita still support the current API with multi-active functionality. It still needs tests, but it seems to work fine. Here is the API:

import { EntityState, EntityStore, StoreConfig, MultiActive } from '@datorama/akita';

export interface WidgetsState extends EntityState<Widget>, MultiActive {
}

const initialState = { active: [] }

@StoreConfig({ name: 'widgets' })
export class WidgetsStore extends EntityStore<WidgetsState, Widget> {
  constructor() {
    super(initialState);
  }
}

Store -

setActive([1, 2, 3]) <=== (still the same)
addActive(id | ids[])
removeActive(id | ids[])
toggleActive(id | ids[])
updateActive()

Query - (still the same API but support multi)

selectActive() : Observable<Entity[]>;
selectActiveIds() : Observable<ID[]>;
getActive(): Entity[];
getActiveId() : ID[];

Released in v2.0.0

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DanielNetzer picture DanielNetzer  路  5Comments

hoisel picture hoisel  路  5Comments

jvitor83 picture jvitor83  路  3Comments

stephencarr picture stephencarr  路  4Comments

hoisel picture hoisel  路  5Comments