5 votes

Retourner un Observable vide à partir d'un Service Angular2

Je suis en train de construire une application Angular 2, qui utilise un service pour collecter des données. Le service contient la logique suivante :

/* ========== CORE COMPONENTS ========== */
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

/* ========== MODELS ========== */
import { IApplicationViewModel } from './models/application.model';

/* ========== CONSTANTS ========== */
import { LogzillaServerConfiguration } from '../../app.configuration';

@Injectable()
export class ApplicationService {
    private getAllEndpoint = LogzillaServerConfiguration.host + '/api/administration/application/getAll';

    // Initializes a new instance of the 'ApplicationService'.
    constructor(private http: Http) { }

    // Get all the 'logzilla' applications.
    getApplications(): Observable<IApplicationViewModel[]> {
        return this.http.get(this.getAllEndpoint)
            .map((response: Response) => <IApplicationViewModel[]>response.json().model)
            .catch(this.handleError);
    }

    // Handle an error that occured while retrieving the data.
    // This method will throw an error to the calling code.
    private handleError(error: Response) {
        return Observable.empty();
    }
}

Ce service récupère des données à partir d'un point de terminaison et les associe à un modèle. Lorsqu'une erreur se produit, je renvoie un message vide. Observable .

J'ai également un résolveur, qui est utilisé pour charger les données du service, avant que la route active ne soit modifiée. Ce résolveur contient la logique suivante :

/* ========== CORE COMPONENTS ========== */
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';

/* ========== APPLICATION SERVICES ========== */
import { ApplicationService } from './application.service';

/* ========== MODELS ========== */
import { IApplicationViewModel } from './models/application.model';
import { IApplicationLogLevel } from './models/applicationLevel.model';

// Defines the 'resolver' which is used to resolve the applications.
@Injectable()
export class ApplicationResolver implements Resolve<IApplicationViewModel[]> {

    // Initializes a new instance of the 'ApplicationResolver'.
constructor(private applicationService: ApplicationService) { }

// Get all the registered applications.
resolve(route: ActivatedRouteSnapshot) {
    return this.applicationService.getApplications();
}
}

La définition de mon itinéraire est la suivante :

{ path: 'applications', component: ApplicationComponent, pathMatch: 'full', resolve: {
            application: ApplicationResolver
        }},

Cependant, lorsque je navigue vers /applications je suis accueilli avec une erreur Uncaught (in promise): Error: no elements in sequence. .

Edit : Ajout d'un composant

@Component({
    selector: 'logzilla-applications',
    templateUrl: './src/app/pages/applications/application.template.html'
})
@Injectable()
export class ApplicationComponent implements OnInit {
    hasApplications: boolean;
    applications: IApplicationViewModel[];
    errorMessage: string;

    // Initializes a new instance of the 'ApplicationComponent'.
    constructor (private route: ActivatedRoute) { 
        console.log('I am here.');
    }

    // This method is executed when the component is loaded.
    ngOnInit() { 

    }

Le constructeur de mon composant n'est pas appelé par un événement. Comment résoudre ce problème ?

Cordialement,

10voto

Christopher Moore Points 2219

Remplacer Observable.empty() con Observable.of([]) . La préférence de of en empty est ce que la version officielle d'Angular Tour des héros utilise pour retourner un observable vide, et c'est ce que j'ai utilisé dans toutes mes applications.

La différence entre les deux semble être de savoir si rien n'est retourné, ou un tableau vide.

Extrait de la documentation officielle de rxjs :

Observable.empty()

Crée un Observable qui n'émet aucun élément vers l'Observateur et émet immédiatement une notification complète.

Observable.of()

Crée un Observable qui émet certaines valeurs que vous spécifiez comme arguments, immédiatement les unes après les autres, puis émet une notification complète.

3voto

M4R1KU Points 706

Le résolveur tente de s'abonner à l'Observable donné et de transmettre le premier résultat de la séquence Observable au composant (en fait l'objet ActivatedRoute).

Mais parce que votre Observable déclenche l'événement completed avant qu'un résultat ne soit émis, le résolveur n'obtient pas de résultat. C'est donc de là que vient votre erreur.

Vous devez retourner soit Observable.of(null) o Observable.of([]) ou quelque chose de similaire. Vous pouvez ensuite gérer l'entrée vide dans votre composant.

Ce site contient de plus amples informations sur le Observable.empty() fonction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X