Handling 204- No Content response in HTTP Observable - Angular2

vigamage picture vigamage · Mar 22, 2017 · Viewed 15.9k times · Source

In my Angular2 application, I am taking responses from a REST API and manipulating them in order to display them in the user interface.

I coded my application according to following tutorial.

https://www.barbarianmeetscoding.com/blog/2016/04/02/getting-started-with-angular-2-step-by-step-6-consuming-real-data-with-http/

This is my method to get the response from server

getTendersByCategory(categoryName: string){

        console.log("get tenders by category "+categoryName);

        let tendersByCategory = this._http
            .get(this._endpointUrl + "tender/get-by-category-name/" + categoryName)
            .map(mapTenders)
            .catch(handleError);

        return tendersByCategory;

}

Following functions are used to manipulate the response

function mapTenders(response: Response): Tender[] {
    console.log('tender.service.ts -> mapTenders');

    /*if(response.status == 204){
        console.log("response = 204 - No content in response");
        return null;
    }*/

    return response.json().map(toTender);
}


function toTender(r: any): Tender {
    console.log('tender.service.ts -> toTender');
    let tender = <Tender>({
        id: r.id,
        name: r.name,
        publisher: r.publisher,
    });
    return tender;
}

function handleError(error: any) {
    console.error(error.message);
    return Observable.throw(error.message);
}

The problem now is, I get 204 - No content response for my requests. In those cases, I get the error

Cannot read property 'map' of null

What I have tried up to now is, I check whether the response is 204 in my mapTenders function; if so I return null without proceeding with mapping to my object. (This part of code has been commented out in the given code)

Is that the correct way of handing this response?

But in that case, even though I get rid of the error, in my .component.ts file I do not get an empty list of tenders. It shows all the tenders without any sort of filtering. (That may be the result from refreshing the entire page, but apparently, page does not reload.)

This is the method in my component.ts file.

getTendersByCategory(categoryName: string){

        this._tendersService.getTendersByCategory(categoryName).
            subscribe(

            tenders => this._tenders = tenders,
            error => this._error_tender = error

            );

       console.log("tenders.component.ts.getTendersByCategory -> tenders array = "+this._tenders.length);

       //for debugging purpose
       //this prints all the tenders. What I wished to see is nothing getting printed
       for(let i=0; i< this._tenders.length;i++){
           printTender(this._tenders[i]);
       }

    }

What can I do here? How should I handle 204 response when using observables ?

Answer

Vignesh picture Vignesh · Mar 22, 2017

You can check the Error Response in service call itself.Try the below code

MethodName(searchLetter: string, gender: string): Observable<Object[]> {
            let dataUrl = 'this._endpointUrl/tender/get-by-category-name/';
            let params = new URLSearchParams;
            params.append('categoryName', categoryName);
            let headers = new Headers();

            return this.http.get(dataUrl, { headers: headers, search: params })
                .map(response =>  { 
                // If request fails, throw an Error that will be caught 
                if(response.status != 200) { 
                throw new Error('This request has failed ' + res.status); } // If everything went fine, return the response 
                else {
                 return response.json(); 
                } }).catch(this.handleError);
        }