import { Injectable } from '@angular/core' ; import { convertToParamMap , ParamMap , Params } from '@angular/router' ; import { ReplaySubject } from 'rxjs' ; import { RouterAdapter , RouterOptions } from '@ngqp/core' ; @ Injectable ( ) export class TestRouterAdapter implements RouterAdapter { private _queryParamMap = new ReplaySubject < ParamMap > ( 1 ) ; public readonly queryParamMap = this . _queryParamMap . asObservable ( ) ; public url : string ; public history : string [ ] = [ ] ; private _params : Params ; private _state : any ; private _trigger : 'imperative' | 'popstate' | 'hashchange' | null ; public navigate ( queryParams , extras = { } ) { this . _trigger = this . _trigger || 'imperative' ; this . _state = extras ? extras . state : null ; const previousUrl = this . url ; const newParams = { ... this . params , ... queryParams , } ; this . params = newParams ; if ( previousUrl && extras . replaceUrl !== true ) { this . history . push ( previousUrl ) ; } this . emitQueryParamMap ( ) ; return Promise . resolve ( true ) . then ( ( ) => this . _state = null ) . then ( ( ) => this . _trigger = null ) ; } public getCurrentNavigation ( ) { return { trigger : 'imperative' as 'imperative' , extras : ! this . _state ? undefined : { state : this . _state } , } ; } public navigateToQueryParamString ( value ) { const params = { } ; const searchParams = new URLSearchParams ( value ) ; const it = ( < any > searchParams ) . keys ( ) ; let current = it . next ( ) ; while ( ! current . done ) { const paramName = current . value ; params [ paramName ] = searchParams . getAll ( paramName ) ; current = it . next ( ) ; } this . _params = { } ; this . _trigger = 'popstate' ; return this . navigate ( params ) ; } public goBack ( ) { if ( this . history . length === 0 ) { return Promise . resolve ( false ) ; } const previous = this . history . pop ( ) ; const result = this . navigateToQueryParamString ( previous ) ; this . history . pop ( ) ; return result ; } private set params ( params ) { this . _params = params ; const urlSearchParams = new URLSearchParams ( ) ; Object . entries ( this . params ) . forEach ( ( [ paramName , value ] ) => { if ( value === undefined || value === null ) { urlSearchParams . delete ( paramName ) ; return ; } this . appendToSearchParams ( urlSearchParams , paramName , value ) ; } ) ; const url = urlSearchParams . toString ( ) ; this . url = url . length !== 0 ? `?${ url }` : '' ; } private get params ( ) : Params { return { ... this . _params } ; } private emitQueryParamMap ( ) { this . _queryParamMap . next ( convertToParamMap ( this . params ) ) ; } private appendToSearchParams ( searchParams , name , value ) { if ( Array . isArray ( value ) ) { value . forEach ( item => this . appendToSearchParams ( searchParams , name , item ) ) ; } else { searchParams . append ( name , `${ value }` ) ; } } }