Ngrx store & effects using Storage?

Having a hard time learning Ngrx effects. I’m using ngrx/store to manage my state. However, I’d like to have Ngrx effects to handle saving to Ionic Storage when state is changed. However, I’m not sure how I can do that.

I have the following code, but dispatching with type UPDATE_SETTINGS won’t get the changed state, so I can’t really change it in the storage. Does anyone have a similar example of using ngrx/effects? anything similar to this would help. Thanks!

import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { Actions, Effect } from "@ngrx/effects";
import {
  GET_SETTINGS,
  UPDATE_SETTINGS,
  UPDATE_SETTINGS_SUCCESS,
  Action,
  AppState
} from '../_reducers/settings.reducer';
import { StorageProvider } from '../providers/storage/storage';
import { Observable } from "rxjs";

const storageKey = 'settings';

@Injectable()
export class SettingsEffects {
  constructor(
    private storage: StorageProvider,
    private actions$: Actions,
    private store$: Store<AppState>
  ) {}

  @Effect() get$ = this.actions$
    .ofType(GET_SETTINGS)
    .mergeMap((action: any) => Observable.fromPromise(this.storage.get(storageKey))
        .map(data => ({ type: UPDATE_SETTINGS, payload: data }))
        .catch(() => Observable.of()))
    .catch(() => Observable.of());

  @Effect() update$ = this.actions$
    .ofType(UPDATE_SETTINGS)
    .switchMap(() => {
      return Observable.of({ type: "UPDATE_SETTINGS_SUCCESS" })
    });

  @Effect() updateSuccess$ = this.actions$
    .ofType(UPDATE_SETTINGS_SUCCESS)
    .do(() => {
      console.log('update settings success called');
    })
    .withLatestFrom(this.store$)
    .switchMap(([ payload, store ] : any) => {
      return Observable.fromPromise(this.storage.set(storageKey, store.settings))
        .catch(() => Observable.of())
    })
    .catch(() => Observable.of());
}

this is my answer to my question.

import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { Actions, Effect } from "@ngrx/effects";
import {
  GET_SETTINGS,
  UPDATE_SETTINGS,
  UPDATE_SETTINGS_SUCCESS,
  Action,
  AppState
} from '../_reducers/settings.reducer';
import { StorageProvider } from '../providers/storage/storage';
import { Observable } from "rxjs";

const storageKey = 'settings';

@Injectable()
export class SettingsEffects {
  constructor(
    private storage: StorageProvider,
    private actions$: Actions,
    private store$: Store<AppState>
  ) {}

  @Effect() get$ = this.actions$
    .ofType(GET_SETTINGS)
    .mergeMap((action: any) => Observable.fromPromise(this.storage.get(storageKey))
        .map(data => ({ type: UPDATE_SETTINGS, payload: data })));

  @Effect() update$ = this.actions$
    .ofType(UPDATE_SETTINGS)
    .withLatestFrom(this.store$, (action, state) => state.settings)
    .map((settings) => settings)
    .switchMap((settings) => {
      // update storage
      this.storage.set(storageKey, settings);
      return Observable.of({ type: "UPDATE_SETTINGS_SUCCESS" })
    });
}

Just writing that I’m not using Ngrx/Store & Ngrx/Effects anymore. It’s so time consuming to use ngrx/store, instead i’ve wrote my own state management using Service, which works way better :slight_smile:

Curious to learn more about this decision. What caused you to give up on the Redux pattern?

2 Likes

That’s not what he said. ngrx is a specific Redux implementation. It is powerful, but it requires a lot of boilerplate, and it takes some time to get your head around, because you need to understand MemoizedSelectors. You can roll your own Redux (without selectors or effects) pretty easily. Maybe he stopped using Redux, I don’t know, but that isn’t the same as ngrx.

Ah, my mistake, I thought a “service” based data store was a distinct pattern from “redux”. There is so much lingo in this corner of eng that I must be confused.

A service is the same as a provider. Any implementation of a data management strategy in Angular will use providers. Redux is the name of a strategy, not an implementation.

@ozexpert Is it an open source code? I would like to see at least your folder structure in project.

@reverYoungFo unfortunately it’s not an open source project.