import { Injectable } from '@angular/core' ; import { Action , State , StateContext , StateToken } from '@ngxs/store' ; import { catchError , tap } from 'rxjs/operators' ; import { UsersStoriesModel } from '../../components/users-stories/users-stories.model' ; import { ApiService } from '../../services/api/api.service' ; import { FetchNewsActions , MainTabsActions , StoriesActions } from './main.actions' ; import { MainPageStateModel , MainTabModel , NewsModel } from './main.model' ; export const initialState = { tabs : { isLoading : true , isFailed : false , isSuccess : false , error : null , listData : [ ] , } , stories : { isLoading : true , isFailed : false , isSuccess : false , error : null , listData : [ ] , } , news : { isLoading : true , isFailed : false , isSuccess : false , error : null , activePage : 1 , pages : [ ] , listData : null , } , } ; export const NEWS_STATE_TOKEN = new StateToken < MainPageStateModel > ( 'main' ) ; @ State ( { name : NEWS_STATE_TOKEN , defaults : initialState , } ) @ Injectable ( ) export class MainPageState { constructor ( private apiService ) { } @ Action ( MainTabsActions . FetchMainTabs ) fetchMainTabs ( ctx , action ) { const state = ctx . getState ( ) ; ctx . patchState ( { tabs : { ... state . tabs , isLoading : true , isFailed : false , isSuccess : false , } , } ) ; return this . apiService . get ( action . api ) . pipe ( tap ( ( tabs ) => ctx . dispatch ( new MainTabsActions . FetchMainTabsSuccess ( tabs ) ) ) , catchError ( ( ) => ctx . dispatch ( new MainTabsActions . FetchMainTabsFail ( 'Error! Please try again.' ) ) ) ) ; } @ Action ( MainTabsActions . FetchMainTabsSuccess ) fetchMainTabsSuccess ( ctx , action ) { ctx . patchState ( { tabs : { listData : action . listData , isLoading : false , isSuccess : true , isFailed : false , error : null , } , } ) ; } @ Action ( MainTabsActions . FetchMainTabsFail ) fetchMainTabsFail ( ctx , action ) { const state = ctx . getState ( ) ; ctx . patchState ( { tabs : { ... state . tabs , isLoading : false , isSuccess : false , isFailed : true , error : action . error , } , } ) ; } @ Action ( StoriesActions . FetchStories ) fetchStories ( ctx , action ) { const state = ctx . getState ( ) ; ctx . patchState ( { stories : { ... state . stories , isLoading : true , isFailed : false , isSuccess : false , } , } ) ; return this . apiService . get ( action . api ) . pipe ( tap ( ( stories ) => ctx . dispatch ( new StoriesActions . FetchStoriesSuccess ( stories ) ) ) , catchError ( ( ) => ctx . dispatch ( new StoriesActions . FetchStoriesFail ( 'Error! Please try again.' ) ) ) ) ; } @ Action ( StoriesActions . FetchStoriesSuccess ) fetchStoriesSuccess ( ctx , action ) { ctx . patchState ( { stories : { listData : action . listData , isLoading : false , isSuccess : true , isFailed : false , error : null , } , } ) ; } @ Action ( StoriesActions . FetchStoriesFail ) fetchStoriesFail ( ctx , action ) { const state = ctx . getState ( ) ; ctx . patchState ( { stories : { ... state . stories , isLoading : false , isSuccess : false , isFailed : true , error : action . error , } , } ) ; } @ Action ( FetchNewsActions . FetchNews ) fetchNews ( ctx , action ) { const state = ctx . getState ( ) ; if ( ! state . news . listData || action . isRefresh ) { ctx . patchState ( { news : { ... state . news , activePage : 1 , pages : [ ] , isLoading : true , isFailed : false , isSuccess : false , } , } ) ; } return this . apiService . get ( action . api ) . pipe ( tap ( ( news ) => ctx . dispatch ( new FetchNewsActions . FetchNewsSuccess ( news , action . page ) ) ) , catchError ( ( ) => ctx . dispatch ( new FetchNewsActions . FetchNewsFail ( 'Error! Please try again.' ) ) ) ) ; } @ Action ( FetchNewsActions . FetchNewsSuccess ) fetchNewsSuccess ( ctx , action ) { const state = ctx . getState ( ) ; const isPageAlreadyExist = state . news . pages . find ( ( page ) => page === action . page ) ; if ( action . listData . length ) { ctx . patchState ( { news : { ... state . news , activePage : action . page , pages : isPageAlreadyExist ? [ ... state . news . pages ] : [ ... state . news . pages , action . page ] , listData : { ... state . news . listData , [ action . page ] : action . listData , } , isLoading : false , isSuccess : true , isFailed : false , error : null , } , } ) ; } } @ Action ( FetchNewsActions . FetchNewsFail ) fetchNewsFail ( ctx , action ) { const state = ctx . getState ( ) ; ctx . patchState ( { news : { ... state . news , isLoading : false , isSuccess : false , isFailed : true , error : action . error , } , } ) ; } }