Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions apps/ngrx-1/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Store } from '@ngrx/store';
import { loadActivities } from './store/activity/activity.actions';
import { ActivityType } from './store/activity/activity.model';
import { selectActivities } from './store/activity/activity.selectors';
import { initApp } from './store/app/app.actions';
import { loadStatuses } from './store/status/status.actions';
import { selectAllTeachersByActivityType } from './store/status/status.selectors';
import { loadUsers } from './store/user/user.actions';
Expand All @@ -29,8 +30,7 @@ import { loadUsers } from './store/user/user.actions';
*ngFor="
let teacher of getAllTeachersForActivityType$(activity.type)
| async
"
>
">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the goal is to avoid calling a function inside a template. The view object should be constructed inside the selector. Thus in the view, only property of that object will be rendered

{{ teacher.name }}
</li>
</ul>
Expand Down Expand Up @@ -63,9 +63,7 @@ export class AppComponent implements OnInit {
activities$ = this.store.select(selectActivities);

ngOnInit(): void {
this.store.dispatch(loadActivities());
this.store.dispatch(loadUsers());
this.store.dispatch(loadStatuses());
this.store.dispatch(initApp());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, that cleaner

}

getAllTeachersForActivityType$ = (type: ActivityType) =>
Expand Down
3 changes: 3 additions & 0 deletions apps/ngrx-1/src/app/store/app/app.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createAction } from '@ngrx/store';

export const initApp = createAction('[AppComponent] initialize Application');
21 changes: 21 additions & 0 deletions apps/ngrx-1/src/app/store/app/app.effects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { flatMap, mergeMap } from 'rxjs/operators';
import * as AppActions from './app.actions';
import * as ActivityActions from '../activity/activity.actions';
import * as UserActions from '../user/user.actions';

@Injectable()
export class AppEffects {
initialiseApp$ = createEffect(() =>
this.actions$.pipe(
ofType(AppActions.initApp),
mergeMap(() => [
ActivityActions.loadActivities(),
UserActions.loadUsers(),
])
)
);

constructor(private actions$: Actions) {}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this effect is not necessary. UserEffect and ActivityEffect can both listen to appAction.initApp.

49 changes: 0 additions & 49 deletions apps/ngrx-1/src/app/store/status/status.effects.ts

This file was deleted.

29 changes: 0 additions & 29 deletions apps/ngrx-1/src/app/store/status/status.reducer.ts

This file was deleted.

40 changes: 31 additions & 9 deletions apps/ngrx-1/src/app/store/status/status.selectors.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { createSelector } from '@ngrx/store';
import { ActivityType } from '../activity/activity.model';
import { statusFeatureKey, StatusState } from './status.reducer';

export const selectStatusState =
createFeatureSelector<StatusState>(statusFeatureKey);
import { selectActivities } from '../activity/activity.selectors';
import { selectUser } from '../user/user.selectors';
import { Status } from './status.model';

export const selectStatuses = createSelector(
selectStatusState,
(state) => state.statuses
selectUser,
selectActivities,
(user, activities): Status[] => {
if (user?.isAdmin) {
return activities.reduce((status: Status[], activity): Status[] => {
const index = status.findIndex((s) => s.name === activity.type);
if (index === -1) {
return [
...status,
{ name: activity.type, teachers: [activity.teacher] },
];
} else {
status[index].teachers.push(activity.teacher);
return status;
}
}, []);
}
return [];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that 's the way to do it, nice

}
);

export const selectTeachersMap = createSelector(selectStatuses, (statuses) => {
const map = new Map();
statuses.forEach((s) => map.set(s.name, s.teachers));
return map;
});

export const selectAllTeachersByActivityType = (name: ActivityType) =>
createSelector(
selectStatusState,
(state) => state.teachersMap.get(name) ?? []
selectTeachersMap,
(teachersMap) => teachersMap.get(name) ?? []
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need the last two selectors. You should create a viewModel with construct your final object that you will use in your view

);
10 changes: 3 additions & 7 deletions apps/ngrx-1/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ import {
activityFeatureKey,
activityReducer,
} from './app/store/activity/activity.reducer';
import { StatusEffects } from './app/store/status/status.effects';
import {
statusFeatureKey,
statusReducer,
} from './app/store/status/status.reducer';
import { AppEffects } from './app/store/app/app.effects';

import { UserEffects } from './app/store/user/user.effects';
import { userFeatureKey, userReducer } from './app/store/user/user.reducer';
import { environment } from './environments/environment';
Expand All @@ -22,14 +19,13 @@ if (environment.production) {
}

const reducers = {
[statusFeatureKey]: statusReducer,
[activityFeatureKey]: activityReducer,
[userFeatureKey]: userReducer,
};

bootstrapApplication(AppComponent, {
providers: [
provideStore(reducers),
provideEffects([ActivityEffects, UserEffects, StatusEffects]),
provideEffects([AppEffects, ActivityEffects, UserEffects]),
],
});