1

Previously my project was on angular2. Now its upgraded to angular6. I am facing some issues regarding the version changes. I will get some json data from an api and I am accessing it through the @angular/http. Following are the angular service I've tried

import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';

 constructor(private http: HttpClient, @Inject('api') private serverApi) { }

  public getResultList(): Promise<any> {
    let uri = `${this.serverApi}/list`;
    return this.http.get(uri)
      .toPromise()
      .then((res) => {
        let temp = res.json();
        return { 'statusCode': 200, 'message': 'success', 'result': temp['items'], 'error': {} };
      })
      .catch((error) => {
        return { 'statusCode': 200, 'message': 'failed', 'result': {}, 'error': error };
      })
  }

I would like to replace the above code to angular6. Following are the code I've tried.

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

 constructor(private http: HttpClient, @Inject('api') private serverApi) { }


 public getResultList(): Observable<any> {
    let uri = `${this.serverApi}/list`;
    return this.http.get<any[]>(uri)
      .pipe(
      tap((res) => {
        let temp = res;
        return { 'statusCode': 200, 'message': 'success', 'result': temp['items'], 'error': {} };
      }),
      catchError((error) => {
        var data = { 'statusCode': 200, 'message': 'success', 'result': {}, 'error': error };
        this.handleError('getResultList', data)
      })
      );
  }

  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.error(error); // log to console instead
      return of(result as T);
    };
  }

Here I am getting the response from the server side but not able to customise the get result and return it from the tap itself. Please help me to resolve the same.

2
  • I would suggest usyn async & await, in that way the data will be in a variable and you could customize that as you want. Commented Jul 31, 2018 at 13:34
  • tap operator is not used to transform your data, you should be able to use the map operator to perform modifications on the data and return it the way you want. learn more: learnrxjs.io/operators/utility/do.html Commented Jul 31, 2018 at 13:37

3 Answers 3

2

Tap is just for actions alongside with the observables, and from the docs:

Tap definition - Transparently perform actions or side-effects, such as logging.


This means that you are actually doing nothing, plus your are not subscribe to the Observable it self. Or if you want to use it as promise you could too, But you still have to do it.

return this.http.get<any[]>(uri)
      .pipe(
      tap(() => {
        console.log("just logging or something");
      }),
      // You have to use map to transform the respond to something else.
      map((res) => { 'statusCode': 200, 'message': 'success', 'result': temp['items'], 'error': {} }),

      catchError((error) => {
        var data = { 'statusCode': 200, 'message': 'success', 'result': {}, 'error': error };
        this.handleError('getResultList', data)
      })
      )

You also may add a map inside the pipe if you want to transform the result to something else.
EDIT--
In you component:

this.service.getResultList()          
.subscribe(
(res) => {
   console.log(res); // <-- Here you can do what ever you want with the result after you subscribe.
},
(err) => {
   console.log(err);
})

You can catch the errors from the subscribe without any problems, then you can handle it in the UI as you wish and also catch the error.

Sign up to request clarification or add additional context in comments.

6 Comments

is it possible to return something to the subscribe even if the catchError happened
sometime the will be down. At that time the control will go to the catchError. I need to pass something to the subscribe to handle the UI part. Now its control is not coming back to the calling function after entering the catchError method.
@LibinCJacob, I've edit the answer, you can catch the error from the subscribe as well. No problem.
I just tried the way you have shared. But the (err) portion is no firing.
Because you are returning normal Observable from the handler, you have to return an actual error, by using something like throwError (rxjs) or something.
|
0

I explained how to return a null from an error() operator. Your code is really. A service should not return the http status code and other header poperties but the real data objects.

Use https://www.npmjs.com/package/class-transformer to convert direcly the json result into real classes. If an error happens then react in the ui.

this.service.getResultList()
.pipe(error(x => {
    return null; // here you return sth to the subscribe
}))
.subscribe(
(res) => {
    if(res == null) return; // then you need to handle this null
    console.log(res); // <-- Here you can do what ever you want with the result after you subscribe.
},
(err) => {
   console.log(err);
})

Comments

-1
  1. Fix the import statements so you can use the HTTP classes without any issues

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

  2. Change the getdata function to this Observable version:

    getdata():Observable{ let url:string=${this.BASE_URL}/fetchdata/ return this.http.get(url); }

1 Comment

console.log("data",data) won't be called.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.