ngrx/store

ngrx/store not working when loading hardcoded data.

katsuragi545 opened this issue · 3 comments

I'm trying to use ngrx/store in my Angular app for hours and I can't figure out what I'm doing wrong. It seems like my store items never get updated.

Here is my Store interface:

export interface ItemStore{
    items: Item[];
}

Item is a custom object - here is the model:

export interface Item {
    id: number;
    name: string;
    description: string;
};

I have a service that acts as a central hub that contain the main 'items' array and a function 'loadItems()' that loads the data (called from another component):

@Injectable()
export class ItemsService {
     items: Observable<Array<Item>>;

     constructor(private http: Http, private store: Store<ItemStore>) {
          this.items = store.select<Array<Item>>('items');
     }
}

loadItems() {
    let initialItems: Item[] = [
        {
            id: 1,
            name: "Item1",
            description: "Description 1"
        },
        {
            id: 2, 
            name: "Item2",
            description: "Description 2"
        }
    ];
    this.store.dispatch({ type: 'LOAD_ITEMS', payload: initialItems });
}

and here is my main app component that calls 'loadItems';

export class HomeComponent implements OnInit {
     items: Observable<Array<Item>>;

     constructor(private itemService: ItemService, private store: Store<ItemStore>) {
          this.items = itemsService.items;
     }
}

and the html I am using to test to see if 'items' is ever updated (it's a simple div that draws a specific number of buttons based on the size of items, which after running my code and loading the manual data should be 2):

        <div *ngFor="let item of items | async">
            <button type="button" pButton icon="fa-check" label=Item: {{item.description}}></button>
        </div>

Any idea what is going on? I'm completely new to ngrx/store and the tutorials I've read haven't been too helpful - they all seem to have syntax errors and are sometimes outdated.

May i see the app.module.ts file ?

@giwiro Here you go:

// <reference path="../../node_modules/angular2/typings/browser.d.ts"/>

import { CoreService } from "./services/core.service";
import { FileManagerComponent } from "./components/file-manager.component";
import { HomeComponent } from "./components/home.component";
import { AboutComponent } from "./components/about.component";

import { routing, appRoutingProviders } from "./file-manager.routing";

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { HttpModule } from "@angular/http";

import { DataListModule } from "primeng/primeng"; 
import { ButtonModule } from "primeng/primeng"; 
import { DialogModule } from "primeng/primeng"; 
import { PanelModule } from "primeng/primeng"; 
import { AccordionModule } from "primeng/primeng"; 
import { TreeModule } from "primeng/primeng";
import { InputTextModule } from "primeng/primeng";
import { ConfirmDialogModule, ConfirmationService } from 'primeng/primeng';

import { mainStoreReducer, fileSetReducer } from "./state-management/reducers/file-manager-reducer";
import { StoreModule } from "@ngrx/store";

@NgModule({
    imports: [
        BrowserModule,
        HttpModule,
        FormsModule,
        routing,
        DataListModule,
        ButtonModule,
        DialogModule,
        PanelModule,
        AccordionModule,
        TreeModule,
        InputTextModule,
        ConfirmDialogModule,
        StoreModule.provideStore({ fileSetReducer })
    ],
    declarations: [
        FileManagerComponent,
        HomeComponent,
        AboutComponent
    ],
    providers: [
        CoreService,
        appRoutingProviders,
        ConfirmationService
    ],
    bootstrap: [FileManagerComponent]
})
export class FileManagerModule { }

I managed to get this working by doing the following (note - this is not how the ngrx/store tutorial explains it - I'm unsure why their instructions don't work for me):

export class HomeComponent implements OnInit {
     items$: Observable<Array<Item>>;

     constructor(private itemService: ItemService, private store: Store<ItemStore>) {
                  store.select('mainReducer')
                       .subscribe((data: ItemStore) => {

                if (typeof data != 'undefined') {
                    this.items$ = Observable.of(data.customObjects);
                }
            });
     }
}

and the reducer function:

export const mainReducer: ActionReducer<ItemStore> = (state: ItemStore, action: Action) => {

    if (typeof state == 'undefined') {
        state = initialState; 
    }

    switch (action.type) {
        case LOAD_ITEMS:
            return {
                items: action.payload
            }
        default: {
            return state;
        }
    }
}