ngrx / store

RxJS powered state management for Angular applications, inspired by Redux

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ImmutableJs not fully working (?)

maxime1992 opened this issue · comments

Hi,

I plan to use ngrx on a large application.

I tried to build a reducer in order to handle a user :

import { ActionReducer, Action } from '@ngrx/store';
import { Map, fromJS } from 'immutable';

// actions
export const USR_CONNECT = 'USR_CONNECT';
export const USR_DISCONNECT = 'USR_DISCONNECT';

interface IUser {
  name?: string,
  isConnected: boolean
};

let initialUser = Map({
  isConnected: true
});

export const UserReducer: ActionReducer<Map<string, any>> = (userState: Map<string, any> = initialUser, action: Action) => {
  switch (action.type) {
    case USR_CONNECT:
      return userState.setIn(['isConnected'], true);

    case USR_DISCONNECT:
      return userState.setIn(['isConnected'], false);

    default:
      return userState;
  }
};

My component looks like this :

import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { USR_CONNECT, USR_DISCONNECT } from '../reducers/user.reducer';

interface IUser {
  name?: string,
  isConnected: boolean
};

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent {
  private user: Observable<IUser>;

  constructor(public store: Store<IUser>) {
    this.user = store.select('user');
  }
}

And within my app.module.ts I have in NgModule/imports :

...
StoreModule.provideStore({
  user: UserReducer
})
...

The problem here is (probably with immutableJs).
In my view :

<div [style.color]="(user | async).isConnected ? 'green': 'red'">is user connected ?</div> {{ (user | async) | json }}

<div *ngIf="(user | async).isConnected">Is connected !</div>
<div *ngIf="!(user | async).isConnected">Is NOT connected !</div>

It's always red and NOT connected. BUT, The json display is :
{ "isConnected": true }

I think I might need to convert the immutable object to a Javascript object.

Any idea on that ?

After some research, I found this library : https://www.npmjs.com/package/ng2-storeservice
And this part is interesting : https://www.npmjs.com/package/ng2-storeservice#usage-with-immutable-structures

StoreService.setTransformFunction(obj => obj.toJS());

Is there something similar with ngrx ?

Thanks for any help =)

In LoginComponent, the declaration user: Observable<IUser>; doesn't match the data coming out of the store, which will be an Observable<Map<string, any>>. This is an ongoing irritation of using a data structure library like ImmutableJS - it moves the actual data types up beyond where the Typescript type system can reach them. In you case I think you can easily get an Observable<IUser> by adding .map(x => x.toJS()) to the end of your select(...) invocation - though Typescript has no way of knowing if this type is true.

(I haven't used ng2-storeservice, and the question about it maybe goes in its repo or other communication channel?)

Thanks @kylecordes & @awerlang !

I did found @teropa repo https://github.com/teropa/harmonics-explorer which is make with typed reducers and I love this way of doing it.

I'll give a try.

Cheers !