2
votes

I'm using NGRX with Nativescript Angular to store state and fetching data from server. However everytime if i suspend the app (IOS) when the app is fetching data from server, the whole process will stop and loses all its states. When i open and resume the app, no data is being returned. Is there any method that i can handle this?

Here are the process:

component.ts (Calling NGRX action to load data) -> actions.ts (Trigger Effect to load data) -> effects.ts (Call service to load data from server, this would be cancelled if the app is suspend and resume during this process)

component.ts

this.store.dispatch(new DataActions.LoadData(this.pageNumber));

action.ts

export class LoadData implements Action {
readonly type = ActionTypes.LoadData;

constructor(
    public pageNumber: number) {
        console.log('load more data action'); //This is seen in the log
    }
}

effect.ts

@Effect()
    loadData$: Observable<Action> = this.actions$.pipe(
        ofType<DataActions.LoadData>(
            DataActions.ActionTypes.LoadData
        ),
        mergeMap((action: DataActions.LoadData) => 
            this.dataService.getData(action.pageNumber).pipe(
                map((data: any) => {
                    console.log(data.result); //This is not seen in the log when app is suspend
                    return new DataActions.LoadDataSuccess(data.result);
                }),
                catchError(err => of(new DataActions.LoadDataFailed(err)))
            )
        )
    );

dataService.service.ts

getData(pageNumber: number): Observable<PaginatedResult<Data[]>> {
const paginatedResult: PaginatedResult<Data[]> = new PaginatedResult<Data[]>();
let queryString = '?';

if (pageNumber != null) {
  queryString += 'pageNumber=' + pageNumber ;
}

return this.http
.get(this.baseUrl + queryString, {observe: 'response'})
  .pipe(
      map((response: any) => {
        paginatedResult.result = response.body;

        console.log(paginatedResult.result); //This is not seen in the log if app suspend

        return paginatedResult;
      })
  );

}

1
you can create another layer which also stores your data to localstorage. I think of usage the metaReducer feature. ngrx.io/guide/store/metareducersenno.void

1 Answers

1
votes

I have often use ngrx-store-localstorage when I need to preserve some NGRX state.

It can be easily configured in your Angular module:

import { StoreModule, Action, ActionReducer, MetaReducer } from '@ngrx/store';

import { localStorageSync } from 'ngrx-store-localstorage';

const STORE_KEYS_TO_PERSIST = [
  'stateKey1',
  'stateKey2'
];

export function localStorageSyncReducer(reducer: ActionReducer<YourAppState>): ActionReducer<YourAppState> {
  return localStorageSync({
    keys: STORE_KEYS_TO_PERSIST,
    rehydrate: true,
  })(reducer);
}

export const metaReducers: Array<MetaReducer<YourAppState, Action>> = [localStorageSyncReducer];

@NgModule({
  imports: [
    ...
    StoreModule.forFeature('your-app', reducers, {
      metaReducers
    }),
    ...
  ],

You only need to configure the store slices that you want to sync - in the example, STORE_KEYS_TO_PERSIST - and the library will handle the store data synchronization for you.

Please, be aware that I never tested it in mobile based Angular applications, although I think it must work out of the box.