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?)
See #23
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 !