on(..)
from the LeaderboardReducer
to some other files like LeaderboardActivityReducer
. Somehow I can't find the right ay to do it. Does anyone have a solution for this?
@hmaidithamer First, try to work around it.
second, dispatch(myaction(data, tag)
, then in the effect
createAction((() =>
this.actions$.pipe(
ofType(myaction),
mergeMap(action => myapicall(action.data).pipe(
map(response => myresponseaction({response: response, tag: action.tag}),
//error handle
)))
then in the selector, watch for the tag with a parameterized selector https://timdeschryver.dev/blog/parameterized-selectors, where the tag is the parameter, and the selector will fire when it sees the tag in the state.
My preference is to try to figure out a way that it isn't needed. If you have an entity with the tag or id as key, before you start make sure it is clear, then select on that id or key and the data will be what you want.
Hi everyone! I just released NgRx Handlers - A plugin for boilerplate elimination. I would appreciate if you check it out and let me know what you think :)
@derekkite Thank you for responding, I have 2 Modules in my main angular app they both have states and registering asPeripheralCommLayerModule
@NgModule({
declarations: [PeripheralCommLayerComponent],
imports: [
StoreModule.forFeature(peripheralIntegrationFeatureKey, peripheralReducer)
],
exports: [PeripheralCommLayerComponent]
})
export class PeripheralCommLayerModule {
static forRoot(environment): ModuleWithProviders<PeripheralCommLayerModule> {
return {
ngModule: PeripheralCommLayerModule
, providers: [{ provide: ENVIRONMENT, useValue: environment }]
};
}
}
FuseDeviceTesterModule
@NgModule({
imports: [
EffectsModule.forFeature([DeviceTesterEffect]),
StoreModule.forFeature(fuseDeviceTesterFeatureKey, fuseDeviceReducer),
],
declarations: [
FuseDeviceTesterComponent,
],
exports: [FuseDeviceTesterComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class FuseDeviceTesterModule {
static forRoot(environment): ModuleWithProviders<FuseDeviceTesterModule> {
return {
ngModule: FuseDeviceTesterModule,
providers: [{ provide: ENVIRONMENT, useValue: environment }]
};
}
}
I am importing PeripheralCommLayerModule
in my app.module.ts
@NgModule({
declarations: [
AppComponent,
],
imports: [
PeripheralCommLayerModule.forRoot(environment),
EffectsModule.forRoot([]),
StoreModule.forRoot({}, { metaReducers }),
// !environment.production ? StoreDevtoolsModule.instrument({ maxAge: 25 }) : []
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
bootstrap: [AppComponent]
})
export class AppModule { }
And FuseDeviceTesterModule
is a lazy-loaded module, which is loaded when I route to a particular URL.
When FuseDeviceTesterModule
is is firing @ngrx/store/update-reducers
action which is received by PeripheralCommLayerModule's reducer and after it selector of PeripheralCommLayerModule is getting fired.
Reducer of PeripheralCommLayerModule :
export const peripheralIntegrationFeatureKey = 'peripheralIntegrationState';
export interface PeripheralIntegrationState {
peripheralServerInstanceInfo: PeripheralServerInstanceInfo;
}
export const initialState: PeripheralIntegrationState = {
peripheralServerInstanceInfo: {
peripheralServerIP: 'localhost',
peripheralServerPort: 47017
},
};
const peripheralIntegrationReducer = createReducer(
initialState,
on(UpdatePeripheralServerPortAndIP, (state, payload) => ({
...state,
peripheralServerInstanceInfo: payload.peripheralServerInstanceInfo
})),
);
export function peripheralReducer(state: PeripheralIntegrationState, action: Action): PeripheralIntegrationState {
return peripheralIntegrationReducer(state, action);
}
on
method or returns current state as a default case, my problem here is when fusedeviceTesterModules get loaded it dispatch`@ngrx/store/update-reducersand somehow it is triggering the selector i have on
peripheralServerInstanceInfo` , i am not able to understand why the selector is triggering if their is no change in my state.
@derekkite, Thanks for guiding me in the right direction, and yes that is what causing the problem, I have both my states(of both modules) synced with localStorage, and when fusedeviceTesterModules
is loaded it updates the localStorage by dispatching @ngrx/store/update-reducer
and my local-storage is updating store of PeripheraCommLayer module
(somehow it is not able to identify the store has same data that is in the localStorage :-( ) and as the store is updated my selector again is not able to identify that store has same data (as my selector is slicing the store on an object and because of store immutability principle(or recommendation) a===b
reference check is not able to determine that deeply the object still contains same data as store now has a new object).
I have written an IsEqual
function and now I am using createSelectorFactory
instead of createSelector
and passing it custom memoization
function:
const isEqualFunc = (last: any, current: any) => {
let flag: boolean = last && current || last === current;
if (last && current) {
const prevProps: string[] = Object.keys(last);
const nextProps: string[] = Object.keys(current);
flag = prevProps.length === nextProps.length;
if (flag) {
for (let i = 0; i < prevProps.length; i++) {
if (typeof last[prevProps[i]] === 'object') {
if (!isEqualFunc(last[prevProps[i]], current[prevProps[i]])) {
flag = false;
break;
}
}
else {
if (last[prevProps[i]] !== current[prevProps[i]]) {
flag = false;
break;
}
}
}
}
}
return flag;
};
const customMemoize = (projectFunc) => resultMemoize(projectFunc, isEqualFunc);
export const getSomeInstance: MemoizedSelector<object, SomeInstance> = createSelectorFactory(customMemoize)(
selectFeatureStoreSlice,
state => state.someInstance
);
it's now working fine.
Can someone please verify and tell me if I am handling the scenario correctly, Thanks in advance :-)
I have a reducer with the following state type:
{
loading: boolean;
info: {
property: string;
something: string;
}
}
On listening to an action i should return that same type to the state. I'm doing the following:
{
...state,
loading: true,
property: 'something
}
Shouldnt i need to do:
{
...state,
loading: true,
info: {
...state.info,
property: 'something
}
}
I'm asking because i always did the latter but VSCode isnt giving me any warning/error.
I'm doing some legacy code refactor so i'm not able to run the project atm, too many things are breaking.
Andreas Weinzierl
why are you cross posting?
Andreas Weinzierl
then you should get an error if you return trash
Hi there I have this effect:
loadTasks$ = createEffect(() =>
this.actions$.pipe(
ofType(fromTasksAction.loadTasks),
withLatestFrom(this.store.select(selectTasks)),
mergeMap(() =>
this.tasksService.getPotOwnersTasks().pipe(
map(tasks => fromTasksAction.loadTasksSuccess({ tasks })),
// delay(1000),
// repeat(),
catchError(error => of(fromTasksAction.loadTasksFailure({ error })))
)
)
)
);
in my component.ts I call this effect with:
ngOnInit(): void {
this.store.dispatch(loadTasks());
this.loadTasks();
loadTasks() {
this.tasks$ = this.store.pipe(shareReplay(1), select(selectTasks));
}
so my store is:
Now I need to fetch the single object from store:
my get in service is:
getTask(containerId, taskInstanceId): Observable<Tasks> {
const url = this.apiUrl + 'containers/' + containerId + '/tasks/' + taskInstanceId;
return this.http.get<Tasks>(url, this.options);
}
How can I loop in store and display the single task from tasks list in store?
thanks a lot
Hello, I have this long lasting question. Is it ok to use one selector as a "prop source" of another
e.g
selector 1 : selectBookById = createSelector(selectBooks, (books, props) => books.filter(book => book.id === props.id))
selector 2 : selectActiveId = crateSelector(selectActiveIdState, (activeIdState) => activeIdState.activeId)
and now
selectActiveBook = createSelector(
booksStateAndActiveIdState => booksStateAndActiveIdState,
selectActiveId,
(booksStateAndActiveIdState, activeID) => selectActiveId(booksStateAndActiveIdState, {id: activeId})
)
Elaboration: I find myself often duplicating selectors for specific entity by its ID and also i have selectors for "active" entities e.g. ones that are in url param in given moment
I would like to write ...byId
selectors and latter only enhance them with active
is the way above valid ?
Does anyone know how or have links for using StoryBook & Angular with NGRX Store ?
I have followed the StoryBook tutorial but still cannot figure out how to use StoryBook with NGRX Store. I can use StoryBook with Angular Dumb Components fine. I need to be able to set the NGRX Store State for the stories of my Nested components.
eg. In my SmartComponent I have:
this.accountDebtor$ = this.coreStore.select( coreSelector.selectAccountDebtorState );
In the Story I have:
export const LoadedAccountPanel = (args) => ({
component: AccountComponent,
props: args,
});
LoadedAccountPanel.args = {
panelData: {},
accountDebtor$: <-- How do I set the State so this gets set using the store ???,
};
Hi all,
Anyone see errors like this after running:nx update
&& then npm run audit
??
npm ERR! code ELOCKVERIFY
npm ERR! Errors were found in your package-lock.json, run npm install to fix them.
npm ERR! Invalid: lock file's @ngrx/schematics@10.1.0 does not satisfy @ngrx/schematics@10.0.0
npm ERR! Invalid: lock file's @ngrx/store-devtools@10.1.0 does not satisfy @ngrx/store-devtools@10.0.0
The actual app works fine - using nx serve
I want to fix the errors so I can run my Jenkins job.
Any advice?