Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I modify the response to an HTTP request and easily access it before return it out from Observable?

Tags:

angular

rxjs

I'm upgrading to Angular to version 5, I was using @angular/http before and now I need to update to @angular/common/http and use HttpClient

I already just make http requests in services (not in components) and that makes them easy to reuse

This is what I already have (from deprecated http)

return this.http.get(url, {headers: this.headers}).map(
      (response: Response) => {
        const data = response.json();
        // Does something on data.data
        
        // return the modified data:
        return data.data;
      }
    ).catch(
      (error: Response) => {
        return Observable.throw(error);
      }
    );

Now from what I learned from new HttpClient it's like I can't modify the response and give it to the component method which is subscribing to it.

how should I modify the response to an HTTP request and easily access it before return it out from Observable?

I just want the same ability to modify the response which I get from API... Like adding some item to it, or do some more stuff to it before returing it

like image 533
John Three Avatar asked Dec 03 '17 09:12

John Three


People also ask

How to modify request header and response header in requestly?

All you need is to install Requestly extension in your browser. Modify Headers could be selected after clicking on New Rule button. Select if you want to modify request header or response header and give a suitable name and description to the rule. Step 1. Select Header Type — Request Headers or Response Headers

How do I Close an HTTP request?

This is done by setting the HTTP header Connection to Close. If we did not set this header, the browser would attempt to keep the connection open (or keep it alive), and you would see the page appear to be loading for a very long time: Returning this object means that the request will be short circuited.

What does “return this object” mean in a request?

Returning this object means that the request will be short circuited. The request is no longer passed through to the URL, and is instead handled directly by BrowserMob, in this case, with an empty response and the supplied HTTP response code:

How do I set the HTTP protocol version of a request?

The first is the HTTP protocol version, which we set to the same version as the request. The second is the HTTP response code, which we set to the value passed into the alterRequestTo () method: We then need to indicate this request should not use the HTTP keep alive functionality. This is done by setting the HTTP header Connection to Close.


2 Answers

It all depends on the version of RxJs. Angular 6 shipped with RxJs 6 - which means that the map()/catch() approach is no longer valid.

Instead, you have to use pipe + map()/catchError() as shown below:

Before Angular 6 / RxJs 6 - classic Http use:

return this.http.get(url, {headers: this.headers}).map(
  (response: Response) => {
    const data : SomeType = response.json() as SomeType;
    // Does something on data.data

    // return the modified data:
    return data.data; // assuming SomeType has a data properties. Following OP post
  }
).catch(
  (error: Response) => {
    throwError(error); // From 'rxjs'
  }
);

Should be changed to this:

After Angular 6 / RxJs 6 - HttpClient migration:

return this.http.get<SomeType>(url, {headers: this.headers})
  .pipe(
     map( response => {  // NOTE: response is of type SomeType
         // Does something on response.data
         // modify the response.data as you see fit.

         // return the modified data:
         return response; // kind of useless
     }),
     catchError( error => {
         return throwError(error); // From 'rxjs'
     })
  ); // end of pipe

In the pipe, map() will pick up the response object (already parsed from JSON) and catchError() will pick up the first error if the HTTP fails.

Also, note that your Headers need to be HttpHeaders object too.

Read on pipe, map and catchError in RxJs 6

like image 123
Max Avatar answered Sep 18 '22 13:09

Max


My service

import {HttpClient} from '@angular/common/http';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class DataService {
    constructor(private http: HttpClient) {}
    getData()
    {
        return this.http.get('../assets/data.json').map(data=>{
            return this.process(data);
        }).catch(
            (error: Response) => {
              return Observable.throw(error);
            });
    }
    process(data:any)  
    {
        let dataTransform:any[]=[];
        let i:number=0;
        for (let item of data)
        {
            dataTransform.push({"id":i,"key":item.key});
            i++;
        }
        return dataTransform;
    }
}

//My component

export class AppComponent implements OnInit {
  constructor(private dataService:DataService){}
  ngOnInit(){
    this.dataService.getData().subscribe((data:any)=> {
      console.log(data);
    });
  }
}

//the asset/data.json

[
    {"key":"uno"},
    {"key":"dos"},
    {"key":"tres"},
    {"key":"cuatro"},
    {"key":"cinco"}
]
like image 20
Eliseo Avatar answered Sep 18 '22 13:09

Eliseo