import { Injectable , EventEmitter } from 'angular2/core' ; import { Http } from 'angular2/http' ; import 'rxjs/add/operator/map' ; import { IUser } from './interfaces' ; const SEED_URL = 'http://api.randomuser.me/?results=10&seed=885ad8c4404e07ea03' ; const URL = 'http://api.randomuser.me/?results=10' ; export { IUser } from './interfaces' ; @ Injectable ( ) export class UserService { usersCache = < Array < IUser > > [ ] ; loading = false ; currentUser : IUser ; currentFetches = new Map < String , Promise < Array < IUser > > > ( ) ; loadingStatus : EventEmitter < boolean > = new EventEmitter ( ) ; constructor ( private http ) { } getUsers ( ) { if ( this . usersCache . length ) { return new Promise ( ( resolve ) => resolve ( this . usersCache ) ) ; } else { return this . fetch ( SEED_URL ) ; } } getMoreUsers ( ) { return this . fetch ( URL ) ; } getUser ( username ) { return this . findUserByUsername ( username ) . then ( user => { this . currentUser = user ; return this . currentUser ; } ) ; } toggleState ( force ) { if ( typeof force === 'undefined' ) { this . loading = ! this . loading ; } else { this . loading = force ; } this . loadingStatus . emit ( this . loading ) ; } saveUser ( user ) { this . usersCache . push ( user ) ; this . sort ( ) ; } sort ( ) { this . usersCache . sort ( ( a , b ) => a . name . last > b . name . last ? 1 : - 1 ) ; } private fetch ( url ) { if ( ! this . currentFetches . has ( url ) ) { let promise = new Promise ( ( resolve , reject ) => { this . toggleState ( true ) ; this . http . get ( url ) . map ( res => res . json ( ) . results ) . map ( res => res . map ( o => o . user ) ) . subscribe ( res => { res . forEach ( user => this . usersCache . push ( user ) ) ; this . sort ( ) ; this . toggleState ( false ) ; this . currentFetches . delete ( url ) ; resolve ( this . usersCache ) ; } ) ; } ) ; this . currentFetches . set ( url , promise ) ; } return this . currentFetches . get ( url ) ; } private findUserByUsername ( username ) { return new Promise ( resolve => { this . getUsers ( ) . then ( users => { let user = users . filter ( user => user . username === username ) [ 0 ] ; resolve ( user ) ; } ) ; } ) ; } }