Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return an empty Observable from an Angular2 Service

Tags:

angular

I'm building an Angular 2 application, which uses a service to gather data. The service does contain the following logic:

/* ========== 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();
    }
}

What this service does is retrieving data from an endpoint, and map it to a model, when an error does occur, I'm returning an empty Observable.

I also have a resolver, which is used to load the data from the service, before the active route is changed. This resolver does contain the following logic:

/* ========== 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();
}
}

The definition of my route is:

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

However, when I browse to /applications, I'm greeted with an error Uncaught (in promise): Error: no elements in sequence..

Edit: Added component

@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() { 

    }

The constructor of my component is not event called. How can this be resolved.

Kind regards,

like image 280
Complexity Avatar asked Mar 07 '17 10:03

Complexity


1 Answers

Replace Observable.empty() with Observable.of([]). The perference of of over empty is what the official Angular Tour of Heroes tutorial uses to return an empty observable, and is what I have been using in all my apps.

The difference between them seems to be whether nothing is returned, or an empty array.

From the official rxjs docs:

Observable.empty()

Creates an Observable that emits no items to the Observer and immediately emits a complete notification.

Observable.of()

Creates an Observable that emits some values you specify as arguments, immediately one after the other, and then emits a complete notification.

like image 199
Christopher Moore Avatar answered Oct 04 '22 02:10

Christopher Moore