Skip to content
Snippets Groups Projects
detail.effects.ts 3.37 KiB
/**
 * This file is part of Anis Client.
 *
 * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

import { Injectable } from '@angular/core';

import { Actions, createEffect, ofType, concatLatestFrom } from '@ngrx/effects';
import { Store  } from '@ngrx/store';
import { of } from 'rxjs';
import { map, tap, mergeMap, catchError } from 'rxjs/operators';
import { ToastrService } from 'ngx-toastr';

import { DetailService } from '../services/detail.service';
import * as detailActions from '../actions/detail.actions';
import * as detailSelector from '../selectors/detail.selector';
import * as attributeSelector from 'src/app/metamodel/selectors/attribute.selector';
import * as datasetSelector from 'src/app/metamodel/selectors/dataset.selector';

/**
 * @class
 * @classdesc Detail effects.
 */
@Injectable()
export class DetailEffects {

    /**
     * Calls actions to retrieve object.
     */
    retrieveObject$ = createEffect((): any =>
        this.actions$.pipe(
            ofType(detailActions.retrieveObject),
            concatLatestFrom(() => [
                this.store.select(datasetSelector.selectDatasetNameByRoute),
                this.store.select(attributeSelector.selectAllAttributes),
                this.store.select(detailSelector.selectIdByRoute)
            ]),
            mergeMap(([action, datasetName, attributeList, id]) => this.detailService.retrieveObject(
                datasetName,
                attributeList.find(attribute => attribute.order_by).id,
                id,
                attributeList.filter(attribute => attribute.detail).map(attribute => attribute.id)
            ).pipe(
                map(object => detailActions.retrieveObjectSuccess({ object: object[0] })),
                catchError(() => of(detailActions.retrieveObjectFail()))
            ))
        )
    );

    /**
     * Displays retrieve object error notification.
     */
    retrieveObjectFail$ = createEffect(() => 
        this.actions$.pipe(
            ofType(detailActions.retrieveObjectFail),
            tap(() => this.toastr.error('Loading Failed!', 'Unable to load the object'))
        ), { dispatch: false}
    );

    /**
     * Calls actions to retrieve spectra.
     */
    retrieveSpectra$ = createEffect((): any =>
        this.actions$.pipe(
            ofType(detailActions.retrieveSpectra),
            concatLatestFrom(() => this.store.select(datasetSelector.selectDatasetNameByRoute)),
            mergeMap(([action, datasetName]) => this.detailService.retrieveSpectra(
                datasetName,
                action.filename
            ).pipe(
                map(spectraCSV => detailActions.retrieveSpectraSuccess({ spectraCSV })),
                catchError(() => of(detailActions.retrieveSpectraFail()))
            ))
        )
    );

    /**
     * Displays retrieve spectra error notification.
     */
    retrieveSpectraFail$ = createEffect(() => 
        this.actions$.pipe(
            ofType(detailActions.retrieveSpectraFail),
            tap(() => this.toastr.error('Loading Failed!', 'Unable to load spectra'))
        ), { dispatch: false}
    );
    
    constructor(
        private actions$: Actions,
        private detailService: DetailService,
        private store: Store<{ }>,
        private toastr: ToastrService
    ) {}
}