import { Injectable } from '@angular/core'; import { ToastrService } from 'ngx-toastr'; import { Effect, Actions, ofType } from '@ngrx/effects'; import {Action, Store} from '@ngrx/store'; import { of } from 'rxjs'; import { map, tap, switchMap, withLatestFrom, catchError } from 'rxjs/operators'; import * as coneSearchActions from './cone-search.action'; import * as fromRouter from '@ngrx/router-store'; import * as fromConeSearch from './cone-search.reducer'; import * as utils from '../../utils'; import { ConeSearchService } from './cone-search.service'; import {FormControl, Validators} from "@angular/forms"; import {nanValidator, rangeValidator} from "../../validator"; @Injectable() export class ConeSearchEffects { constructor( private actions$: Actions, private coneSearchService: ConeSearchService, private toastr: ToastrService, private store$: Store<{ router: fromRouter.RouterReducerState<utils.RouterStateUrl>, search: fromConeSearch.State }> ) { } @Effect() retrieveCoordinatesAction$ = this.actions$.pipe( ofType(coneSearchActions.RETRIEVE_COORDINATES), withLatestFrom(this.store$), switchMap(([action, state]) => { const retrieveCoordinatesAction = action as coneSearchActions.RetrieveCoordinatesAction; return this.coneSearchService.retrieveCoordinates(retrieveCoordinatesAction.payload).pipe( map((response) => { const parser = new DOMParser(); const xml = parser.parseFromString(response,'text/xml'); if (xml.getElementsByTagName('Resolver').length === 0) { const name = xml.getElementsByTagName('name')[0].childNodes[0].nodeValue; return new coneSearchActions.RetrieveCoordinatesFailAction(name); } const name = xml.getElementsByTagName('name')[0].childNodes[0].nodeValue; const ra = +xml.getElementsByTagName('jradeg')[0].childNodes[0].nodeValue; const dec = +xml.getElementsByTagName('jdedeg')[0].childNodes[0].nodeValue; return new coneSearchActions.RetrieveCoordinatesSuccessAction({name, ra, dec}); }), catchError(() => of(new coneSearchActions.RetrieveCoordinatesFailAction(null))) ); }) ); @Effect({ dispatch: false }) retrieveCoordinatesFailAction$ = this.actions$.pipe( ofType(coneSearchActions.RETRIEVE_COORDINATES_FAIL), tap(action => { const retrieveCoordinatesFailAction = action as coneSearchActions.RetrieveCoordinatesFailAction; if (retrieveCoordinatesFailAction.payload) { this.toastr.error(retrieveCoordinatesFailAction.payload + ' not found'); } else { this.toastr.error('Connection to Sesame Name Resolver failed', 'Resolver Failed!'); } }) ); @Effect() addConeSearchFromUrlAction$ = this.actions$.pipe( ofType(coneSearchActions.ADD_CONE_SEARCH_FROM_URL), switchMap(action => { const addConeSearchFromUrlAction = action as coneSearchActions.AddConeSearchFromUrlAction; let raForm = new FormControl('', [Validators.required, nanValidator, rangeValidator(0, 360)]); raForm.setValue(addConeSearchFromUrlAction.payload.ra); let decForm = new FormControl('', [Validators.required, nanValidator, rangeValidator(-90, 90)]); decForm.setValue(addConeSearchFromUrlAction.payload.dec); let radiusForm = new FormControl('', [Validators.required, nanValidator, rangeValidator(0, 150)]); radiusForm.setValue(addConeSearchFromUrlAction.payload.radius); if (!raForm.errors && !decForm.errors && !radiusForm.errors) { const actions: Action[] = []; actions.push(new coneSearchActions.AddConeSearchAction(addConeSearchFromUrlAction.payload)); actions.push(new coneSearchActions.IsValidConeSearchAction(true)); return actions; } else { this.toastr.error('Cone search from URL is not valid', 'Not valid position!'); return of(); } }) ); }