I'm not sure there's much else to say here.
Of note, perhaps, is that EMPTY is an RxJs stream that emits nothing and completes immediately. It is sort of like "break" (in a pretty loose way. How you "break" from a stream can be pretty context dependant).
this.service.create('/api/employee').pipe( catchError(err1 => { // do some stuff return throwError(err1); }), switchMap(resp1 => { // do some stuffs if(someCondition(resp1)){ return this.service.update('/api/salary/', id).pipe( catchError(err2 => { // do some stuff return throwError(err2); }), ); } return EMPTY; }), switchMap(resp2 => { // do some stuff if(someCondition(resp2)){ return this.service.delete('/api/education/', id).pipe( catchError(err3 => { // do some stuff return throwError(err3); }), ); } return EMPTY; }), ).subscribe({ next: resp3 => { /*do some stuff*/ }, complete: () => { /*Your stream is done*/ }, eror: err => { /*All re-thrown errors end up here */ } });
Update
Using tap to help understand streams
tap is an operator that returns the same stream that it receives. It can't make any changes to your stream, but it can look at what is happening at any given point. This can be a useful tool to aid your understanding.
http1().pipe( tap({ next: val => console.log("Result from http1 call: ", val), complete: () => console.log("http1 call completed"), error: err => console.log("http1 call errored: ", err) }) switchMap(val => http2(val).pipe( tap({ next: val => console.log("Result from http2 call: ", val), complete: () => console.log("http2 completed"), error: err => console.log("http2 call errored: ", err) }) )), tap({ next: val => console.log("Result from switchMap operator: ", val), complete: () => console.log("switchMap completed"), error: err => console.log("switchMap (http1 or http2 call) errored: ", err) }) ).subscribe()
Here we can see what is happening before and after the switchMap. You can see that in this case, switchMap is taking a value from http1 and emitting the values from http2.
Because switchMap waits for values from http1 before generating http2, one side effect is that http2 doesn't start until after http1 emits. This does mean that these calls are executed sequentially, but the story gets more complicated if http1 emits more than once.
More About: