import { Injectable } from '@angular/core' ; import { AngularFirestore } from '@angular/fire/firestore' ; import * as firebase from 'firebase' ; import { throwError , Observable } from 'rxjs' ; import { take } from 'rxjs/operators' ; import { first , map , switchMap } from 'rxjs/operators' ; import { v4 as uuid } from 'uuid' ; import { ModelFactory } from '@shared/models/factories/model.factory' ; import { IProject , IToken , ProjectModel , TokenModel } from '@shared/models/index.model' ; import { ProjectService } from './project.service' ; @ Injectable ( { providedIn : 'root' , } ) export class TokenService { param afs param projectService constructor ( private afs , private projectService ) { } param projectUid param tokenUid public findOneById ( projectUid , tokenUid ) { return this . projectService . findOneById ( projectUid ) . pipe ( map ( ( data ) => data && data . tokens && data . tokens . find ( ( item ) => item . uid === tokenUid ) ) ) ; } param projectUid public findAll ( projectUid ) { return this . projectService . findOneById ( projectUid ) . pipe ( map ( ( data ) => Array . isArray ( data . tokens ) ? data . tokens : [ ] ) ) ; } param projectUid param token public save ( projectUid , token ) { return this . projectService . findOneById ( projectUid ) . pipe ( take ( 1 ) , map ( ( project ) => { const tokens = project . tokens ; if ( tokens . find ( ( tokenModel ) => tokenModel . uid === token . uid ) ) { return project . tokens . map ( ( tokenModel ) => { if ( tokenModel . uid === token . uid ) { return new TokenModel ( { ... tokenModel . toData ( ) , ... token . toData ( true ) } ) ; } return tokenModel ; } ) ; } token . uid = uuid ( ) ; token . createdOn = firebase . firestore . Timestamp . fromDate ( new Date ( ) ) ; token . updatedOn = firebase . firestore . Timestamp . fromDate ( new Date ( ) ) ; return project . tokens . concat ( token ) ; } ) , switchMap ( ( tokens ) => this . afs . collection < IProject > ( 'projects' ) . doc < IProject > ( projectUid ) . set ( { tokens : ModelFactory . fromModels < TokenModel , IToken > ( tokens ) , updatedOn : firebase . firestore . Timestamp . fromDate ( new Date ( ) ) , } , { merge : true } ) ) ) ; } param projectUid param tokenUid public delete ( projectUid , tokenUid ) { return this . projectService . findOneById ( projectUid ) . pipe ( first ( ) , switchMap ( ( project ) => { const found = Array . isArray ( project . tokens ) && project . tokens . find ( ( item ) => item . uid === tokenUid ) ; if ( Array . isArray ( project . tokens ) && found ) { project . tokens = project . tokens . filter ( ( item ) => item . uid !== tokenUid ) ; } else { return throwError ( new Error ( 'Token not found.' ) ) ; } return this . projectService . save ( project . toData ( ) ) . pipe ( map ( ( ) => project . tokens ) ) ; } ) ) ; } }