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 _get from 'lodash/get' ; import _without from 'lodash/without' ; import { AppState , ITweet , IUsersState } from '../../reducers' ; import { fetchUserTweets , fetchedUserTweets , errorUserTweets } from '../../actions' ; import { TwitterProvider } from './../twitter/twitter' ; import { createTweetObject } from '../tweet/tweet' ; @ Injectable ( ) export class UserTweetsProvider { constructor ( public store , private twitterProvider ) { console . log ( 'Hello UserTweetsProvider Provider' ) ; } isFetching$ ( username = '' ) { return this . store . select ( state => _get ( state , `userTweets[${ username }].fetching` , false ) ) ; } getUserTweets$ ( username = '' ) { return this . store . select ( state => _get ( state , `userTweets[${ username }].list` , [ ] ) ) ; } getUserTweetsPaginated$ ( username = '' , pageBSubject , perPage = 10 ) { return Observable . combineLatest ( this . getUserTweets$ ( username ) , this . store . select ( state => state . tweets ) , this . store . select ( state => state . users ) , pageBSubject , ( feed , tweets , users , page ) => _without ( _take ( feed , page * perPage ) . map ( tweetId => tweets [ tweetId ] ? createTweetObject ( tweets [ tweetId ] , tweets , users ) : null ) , null ) ) ; } getLastTweetId ( username = '' ) { let lastItem ; this . getUserTweets$ ( username ) . first ( ) . subscribe ( ( items ) => ( lastItem = items [ items . length - 1 ] ) ) ; return lastItem ; } hasUserTweets ( username = '' ) { let hasUserTweets ; this . getUserTweets$ ( username ) . first ( ) . subscribe ( ( items ) => ( hasUserTweets = items . length !== 0 ) ) ; return hasUserTweets ; } userTweetsLength ( username = '' ) { let userTweetsLength ; this . getUserTweets$ ( username ) . first ( ) . subscribe ( ( items ) => ( userTweetsLength = items . length ) ) ; return userTweetsLength ; } fetch$ ( username ) { this . store . dispatch ( fetchUserTweets ( username ) ) ; return this . twitterProvider . getTimeline$ ( username , { include_entities : true } ) . debounceTime ( 500 ) . map ( res => this . store . dispatch ( fetchedUserTweets ( username , res , true ) ) ) . catch ( error => { console . error ( 'fetch$' , error ) ; this . store . dispatch ( errorUserTweets ( username ) ) ; return Observable . of ( null ) ; } ) ; } fetchNextPage$ ( username ) { const lastTweetId = this . getLastTweetId ( username ) ; if ( ! lastTweetId ) return Observable . of ( null ) ; this . store . dispatch ( fetchUserTweets ( username ) ) ; return this . twitterProvider . getTimeline$ ( username , { max_id : lastTweetId , include_entities : true } ) . debounceTime ( 500 ) . map ( res => this . store . dispatch ( fetchedUserTweets ( username , res ) ) ) . catch ( error => { console . error ( 'fetchNextPage$' , error ) ; this . store . dispatch ( errorUserTweets ( username ) ) ; return Observable . of ( null ) ; } ) ; } }