Question: I need wait for two requests (observables) and do some things.
What i need:

1. Wait for requests (observables) end
2. If one of them failed - display one error
3. If both of them failed - display second error
4. If first success - do some things
5. If second success - do some things

i can combine 4 and 5 if that matter for errors handling.

I tried to use `forkJoin` but it fails at all if one of requests failed.  

I tried to use `concat` but it works the same as `forkJoin`  

I tried to use `combineLatestWith` but it doesn't display errors at all as `combineLatest`  

Finally i tried to use next:

```
const firstRequest$ = this.doFirstRequest(searchRequest);
const secondRequest$ = this.doSecondRequest(searchRequest);
combineLatest([firstRequest$, secondRequest$]).subscribe(([res1, res2]) => {
  console.log(res1, res2);
}, err => {
  console.log(err);
});

```

and now i got only both success results and didn't get any error
What im missing?

Answer: 
catch your errors at the request level and transform them into something usable:

```
const firstRequest$ = this.doFirstRequest(searchRequest).pipe(
  catchError(error => of({error})) 
);
const secondRequest$ = this.doSecondRequest(searchRequest).pipe(
  catchError(error => of({error}))
);
forkJoin([firstRequest$, secondRequest$]).subscribe(([res1, res2]) => {
  if (res1.error && res2.error) {
    // both failed
  } else if (res1.error || res2.error) {
    // one failed
  }
  if (!res1.error) {
    // req 1 success 
  }
  if (!res2.error) {
    // req 2 success
  }
  // whatever you need to do now that they're both done
}, err => {
  // can't get here now
});

```
I had a case where one request normally takes much longer than the other, so in the success case I don't want to have to wait for both requests to finish before continuing. As soon as one request finishes, I want to show the received data to the user.
But the error handling needed to be different if both requests failed, than if just one failed or when both succeeded.

So I did this:

```
getRequestASucceeded$ = new ReplaySubject<boolean>(1);

this.getRequestA()
    .subscribe( dataA => {
       this.getRequestASucceeded$.next(true);
       // continue with dataA
     },
     (err: HttpErrorResponse) => {
        this.getRequestASucceeded$.next(false);
      }
   );

this.getRequestB()
    .subscribe( dataB => {

       // continue with dataB

       this.getRequestASucceeded$.subscribe( hasSucceeded => {
          if (hasSucceeded) {
            // Both Request succeeded
          else {
            // RequestA failed, RequestB succeeded
          }
     },
     (err: HttpErrorResponse) => {

        this.getRequestASucceeded$.subscribe( hasSucceeded => {
          if (hasSucceeded) {
            // RequestA succeeded, RequestB failed
          else {
            // Both Request failed
          }
      }
   );

```

The Errors are only processed after both requests finished, but the individaul data can get processed right away.