Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manipulate data before returning observable

I am pretty new with Angular 2 and the concept of Observables. However what i am trying to achieve should be fairly simple for experienced gurus :)

So: I have a component in which i have subscribed the observable which is coming from a service. For testing purposes, i have been using data Arrays to make my components live. Now that when its done, i want to hook real API calls to my service. Now the problem is that the data that i get from the server needs to be manipulated before its returned to the component. When i manipulate it, i get error such as "cannot read property 'subscribe' of null"

Now basically this error is coming because in my service observable, i send an API request using HTTP.get method and the code doesn't wait for its response to finish. I do get the result from server but that comes after the error in console.

Can anyone please guide me how to request an HTTP call and then manipulate its data before sending it to the component that has the services subscribed?

Here is my component code:

getSearchResults(keyword, parentId?, subCatId?) {
    this.subscriptionResults = this.catalogService.getSearchResults(keyword, parentId, subCatId)
        .subscribe(
            data => {
                this.results                = data.results.parts;
                this.numResults             = data.results.totalItemCount;
                this.timeResults            = data.results.processingTimeMS;
                this.categories             = data.categories;
                this.subCategories          = data.subCategories;
                this.brands                 = data.brands;
                this.suppliers              = data.suppliers;
                this.layoutType             = data.layoutType;
                this.allCategories          = data.allCategories;
                this.selCategoryName        = data.selCategoryName;
                this.selSubCategoryName     = data.selSubCategoryName;

                if ( this.debugMode ) {
                    console.log('RESULTS: ', data);
                }
            },
            error => this.errorMessage = <any>error
        );
}

And here is my service:

// Get data from server
getDataFromServer(URL: string): Observable<any> {
    return this.http.get(URL).flatMap(this.extractData).catch(this.handleError);
}


getSearchResults(keyword: string, parentCatId?:number, subCatId?:number): Observable<any> {

    let request = null;
    let result  = null;

    let URL = this.API_URL + '/search?categoryId=' + subCatId + '&format=json';
    request = this.getDataFromServer(URL);

    request.subscribe(
        () => { 
            // Modify result here and send it back 
        },
        error => { console.log('ERROR: ', <any>error); }
    );

I want to manipulate the response data before i want to return it. How can i do that?

-- EDIT -- If i return a BehaviorSubject:

return new BehaviorSubject<any>(request.subscribe(
            res => { return this.processResultData(res, layoutType, keyword, parentCatId, subCatId); },
            err => { console.log('RETURN ERROR: ', <any>err); }
        ));

I get subscription object in my component (which is what i dont need). Instead i need the data thats inside of the subscription.

like image 596
Hassan Avatar asked Sep 21 '16 14:09

Hassan


People also ask

Is Promises are more advanced than observables?

While an Observable can do everything a Promise can, the reverse is not true. For example, an Observable can emit multiple values over time. A Promise only resolves once. This may lead you to believe that the Observable is BETTER than the Promise.

What is the return type of observable?

Returns Observable Returns an Observable that emits a boolean based on the input value: If no predicate method, the value will be converted to it's Boolean value.


1 Answers

Your component is subscribing to the return value from getSearchResults() so that function needs to return an Observable. Your getDataFromServer() function returns an observable, so what you can do is use Observable.map() on that return value. Observable.map() lets you modify the value moving through an observable stream, and return a new observable of the modified value. That new observable is the one your component will want to subscribe to, so that is what should be returned.

In code, it would look like:

getSearchResults(keyword: string, parentCatId?:number, subCatId?:number): Observable {

    let request = null;
    let result  = null;

    let URL = this.API_URL + '/search?categoryId=' + subCatId + '&format=json';
    return this.getDataFromServer(URL).map(
        (response) => {

            // Modify response here

            // Return modified response
        }
    ).catch((error) => { console.log('ERROR: ', error); });
}

When your component subscribes, it should see the modified response that comes from the .map().

like image 145
Alex Wheeler Avatar answered Sep 20 '22 03:09

Alex Wheeler