0

I'm trying to do the following pseudo code in Angular. For getData1() i'm using a pipe and map but when making the same call to getData2() it's not letting me call map. I also need to be able to unit test getData() this but it seems complex to test nested calls

let data = '';

when called on init
  getData().subscribe(res=>{this.data = res.data})


getData():Observable{
  Make request to getData1()
    if getData1() success
      return response
    () => { // call this if getData1() fails
      if http get to third party api fails (e.g. its down)
        Make request to getData2()
          if getData2() success
            return response
    }
  If both fail
    send error to be handled by another service
}

getData1(): Observable<TestData1Res> {
 return http.get(external url 1);
}
getData2(): Observable<TestData2Res>  {
 return http.get(external url 2);
}

How do I stop the response in the main method call subscribe from erroring with 'Property 'testData' does not exist on type 'TestData1Res| TestData2Res', where only TestData2Res contains property 'testData' The response from both apis will have different properties

e.g .subscribe( (res) => { if (res.testData) { << this errors with that msg } }

2
  • Is the response structure the same, or different for each API?
    – OctavianM
    Commented Dec 3, 2021 at 18:48
  • You can use RxJs catchError operator for a much cleaner solution. The code isn't very readable to be honest, but I hope my comment helps you. You make the first request with the pipe catchError. Inside the catchError you perform the second request. The subscribe will return the first if it works, the second if the first throws an error. Commented Dec 3, 2021 at 19:04

1 Answer 1

2

sandbox link
You can simply use catchError and return the second call when first fails and return response in subscribe, if both calls fails it will enter the error of subscribe.

// a call that always passes
let fakeCall = (d = 10) => of(d);

// a call always fails
let fakeError = (e = 10) => throwError(new Error('fake error!: ' +  e));

// here it will make first call only and ignore second call
fakeCall(10).pipe(catchError(c => fakeCall(20)))
.subscribe((r) => console.log('response', r), 
e => console.log('error',e)); 
// repsponse 10

// here it will make first call but not second so second error has not impact
fakeCall(10).pipe(catchError(c => fakeError(20)))
 .subscribe(
   (r) => console.log('response', r), 
   e => console.log('error',e)); 
   // response 10

// here the it will make second call and return response of second call
   fakeError(10).pipe(catchError(c => fakeCall(20)))
.subscribe(
  (r) => console.log('response', r), 
  (e) => console.log('error',e)); 
  // response 20


fakeError(10).pipe(catchError(c => fakeError(20)))
.subscribe(
(r) => console.log('response', r), 
(e) => console.log('error',e)); 
// error 20

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.