import { BehaviorSubject } from 'rxjs/BehaviorSubject' ; import { Observable } from 'rxjs/Observable' ; import { Injectable } from '@angular/core' ; import { Store } from '@ngrx/store' ; import _take from 'lodash/take' ; import _without from 'lodash/without' ; import { AppState , ITweet , IUsersState } from '../../reducers' ; import { fetchFeed , fetchedFeed , errorFeed } from '../../actions' ; import { TwitterProvider } from './../twitter/twitter' ; import { createTweetObject } from '../tweet/tweet' ; @ Injectable ( ) export class FeedProvider { constructor ( public store , private twitterProvider ) { console . log ( 'Hello FeedProvider Provider' ) ; } isFetching$ ( ) { return this . store . select ( state => state . feed . fetching ) ; } getFeed$ ( ) { return this . store . select ( state => state . feed . list ) ; } getFeedPaginated$ ( pageBSubject , perPage = 10 ) { return Observable . combineLatest ( this . store . select ( state => state . feed . list ) , this . store . select ( state => state . tweets ) , this . store . select ( state => state . users ) , pageBSubject , ( feed , tweets , users , page ) => _without ( _take ( feed , page * perPage ) . map ( tweetId => createTweetObject ( tweets [ tweetId ] , tweets , users ) ) , null ) ) ; } getLastTweetId ( ) { let lastItem ; this . getFeed$ ( ) . first ( ) . subscribe ( ( items ) => ( lastItem = items [ items . length - 1 ] ) ) ; return lastItem ; } hasFeed ( ) { let hasFeed ; this . getFeed$ ( ) . first ( ) . subscribe ( ( items ) => ( hasFeed = items . length !== 0 ) ) ; return hasFeed ; } feedLength ( ) { let feedLength ; this . getFeed$ ( ) . first ( ) . subscribe ( ( items ) => ( feedLength = items . length ) ) ; return feedLength ; } fetch$ ( ) { this . store . dispatch ( fetchFeed ( ) ) ; return this . twitterProvider . getFeed$ ( { include_entities : true } ) . debounceTime ( 500 ) . map ( feed => this . store . dispatch ( fetchedFeed ( feed , true ) ) ) . catch ( error => { console . error ( 'fetch$' , error ) ; this . store . dispatch ( errorFeed ( ) ) ; return Observable . of ( null ) ; } ) ; } fetchNextPage$ ( ) { const lastTweetId = this . getLastTweetId ( ) ; if ( ! lastTweetId ) return Observable . of ( null ) ; this . store . dispatch ( fetchFeed ( ) ) ; return this . twitterProvider . getFeed$ ( { max_id : lastTweetId , include_entities : true } ) . debounceTime ( 500 ) . map ( feed => this . store . dispatch ( fetchedFeed ( feed ) ) ) . catch ( error => { console . error ( 'fetchNextPage$' , error ) ; this . store . dispatch ( errorFeed ( ) ) ; return Observable . of ( null ) ; } ) ; } }