Every time I run the following code:
valueToDisplay$ =store.select('model','sub-model')
The value stored in valueToDisplay$ always corresponds to 'model'. Despite trying various approaches to properly project the state, it seems that I am missing a crucial aspect of how the NGRX store initializes.
AppComponent
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { AppComponent } from './app.component';
import { SetViewComponent } from './set-view/set-view.component';
import { MoveInputComponent } from './move-input/move-input.component';
import { MoveViewComponent } from './move-view/move-view.component';
import { movementsReducer } from './shared/store/set.store';
@NgModule({
declarations: [
AppComponent,
SetViewComponent,
MoveInputComponent,
MoveViewComponent,
],
imports: [
BrowserModule,
StoreModule.forRoot({movementsReducer:movementsReducer})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Reducer: Despite having an extensively layered state object, it does not alter my core strategy so far.
import { DanceSet, Movement } from "../model/model";
import { Action, ActionReducerMap } from "@ngrx/store";
import { Injectable } from "@angular/core";
// STATE
export interface MovementState {
movementsReducer:{
movements?:Movement[],
lastId?:number
},
}
export const INITIAL_STATE:MovementState = {
movementsReducer:{movements:[],lastId:0},
}
// ACTION NAMES
export enum MovementActionTypes {
ADD_MOVEMENT='[MOVEMENT] ADD_MOVEMENT',
REMOVE_MOVEMENT='[MOVEMENT] REMOVE_MOVEMENT'
}
// ACTION CLASSES
export class AddMovementAction implements Action {
readonly type = MovementActionTypes.ADD_MOVEMENT;
constructor(public payload: Movement){};
}
export class RemoveMovementAction implements Action{
readonly type = MovementActionTypes.REMOVE_MOVEMENT;
constructor(public payload:number){};
}
// Action TYPES
export type MovementActions
= AddMovementAction | RemoveMovementAction
//Util
export function filterOutMovement(movements:Movement[], id:number):Movement[]{
return movements.filter(item =>item.id !== id);
}
// Dance Set Reducer
export function movementsReducer(state: MovementState = INITIAL_STATE, action:any ): MovementState{
switch(action.type){
case MovementActionTypes.ADD_MOVEMENT:
return {
...state,
movementsReducer:{movements: [...state.movementsReducer.movements, action.payload], lastId:state.movementsReducer.lastId+1},
}
case MovementActionTypes.REMOVE_MOVEMENT:
return{
...state,
movementsReducer:{movements:filterOutMovement(state.movementsReducer.movements,action.payload), lastId:state.movementsReducer.lastId}
}
default:
return state;
}
}
Current View Component: In my template, I aim to display the current 'movements$', but upon inspecting the object, it appears to be the entire state rather than a slice of it.
import { Component, OnInit } from '@angular/core';
import { MovementState, MovementActionTypes, AddMovementAction } from '../shared/store/set.store';
import { Store, select } from '@ngrx/store';
import { Movement } from '../shared/model/model';
import { Observable } from 'rxjs/Observable';
@Component({
selector: 'app-set-view',
templateUrl: './set-view.component.html',
styleUrls: ['./set-view.component.css']
})
export class SetViewComponent implements OnInit {
public movements$:Array<Movement>;
subscription;
constructor(private store:Store<MovementState>) {
this.subscription = this.store.select('movementsReducer', 'movements').subscribe(value => this.movements$=value);
}
ngOnInit() {
}
addMove(name, id){
let move = new Movement('Test',1);
this.store.dispatch(new AddMovementAction(move));
}
}