Reputation: 506
I am quite new to NGRx, I am trying to use Effects on my little project as date uses external data I decided to put it in the effects, so app now is crashed with infinite loop after running "npm start", it is just stops working. Here is the link to repo Github Repo
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import {
countActionsType,
CountUpdatedAtAction,
} from './reducers/count/count.actions';
import { map } from 'rxjs/operators';
@Injectable()
export class AppEffects {
constructor(private actions$: Actions) {}
@Effect()
updatedAt$() {
return this.actions$.pipe(
ofType(
countActionsType.increase,
countActionsType.decrease,
countActionsType.clear,
countActionsType.updatedAt
),
map(() => {
return new CountUpdatedAtAction({
updatedAt: Date.now(),
});
})
);
}
}
import { CountActions, countActionsType } from './count.actions';
export const COUNT_NODE = 'count';
export interface ICountState {
count: number;
updatedAt: number;
}
const initialState: ICountState = {
count: 0,
updatedAt: Date.now(),
};
export const countReducer = (state = initialState, actions: CountActions) => {
switch (actions.type) {
case countActionsType.increase:
return {
...state,
count: state.count + 1,
};
case countActionsType.decrease:
return {
...state,
count: state.count - 1,
};
case countActionsType.clear:
return {
...state,
count: 0,
};
case countActionsType.updatedAt:
return {
...state,
updatedAt: actions.payload.updatedAt,
};
default:
return state;
}
};
import { Action } from '@ngrx/store';
export enum countActionsType {
increase = '[COUNT] increase',
decrease = '[COUNT] decrease',
clear = '[COUNT] clear',
updatedAt = '[COUNT] updated at',
}
export class CountIncreaseAction implements Action {
readonly type = countActionsType.increase;
}
export class CountDecreaseAction implements Action {
readonly type = countActionsType.decrease;
}
export class CountClearAction implements Action {
readonly type = countActionsType.clear;
}
export class CountUpdatedAtAction implements Action {
readonly type = countActionsType.updatedAt;
constructor(
public payload: {
updatedAt: number;
}
) {}
}
export type CountActions =
| CountIncreaseAction
| CountDecreaseAction
| CountClearAction
| CountUpdatedAtAction;
import { Component } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { ICountState } from './reducers/count/count.reducer';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { selectCount, selectUpdatedAt } from './reducers/count/count.selectors';
import {
CountIncreaseAction,
CountDecreaseAction,
CountClearAction,
} from './reducers/count/count.actions';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
public count$: Observable<number> = this.store$.pipe(select(selectCount));
public isButtonDisabled$: Observable<boolean> = this.count$.pipe(
map((count) => count <= 0)
);
public updatedAt$: Observable<number> = this.store$.pipe(
select(selectUpdatedAt)
);
constructor(private store$: Store<ICountState>) {}
increase() {
this.store$.dispatch(new CountIncreaseAction());
}
decrease() {
this.store$.dispatch(new CountDecreaseAction());
}
clear() {
this.store$.dispatch(new CountClearAction());
}
}
Upvotes: 0
Views: 498
Reputation: 4464
That's quite simple, your effect is triggered when you dispatch some actions, including countActionsType.updatedAt
.
Inside your effect, you dispatch an Action called CountUpdatedAtAction
, that has type countActionsType.updatedAt
.
That's your infinite loop :)
Every time you update, the effect will try to update again, and again, and again :P
To make this work, just remove countActionsType.updatedAt
in:
ofType(
countActionsType.increase,
countActionsType.decrease,
countActionsType.clear,
countActionsType.updatedAt // <--- remove this
),
Upvotes: 1