2

This is more like question than resolve a problem.
I would like to know if there any scenario that both "Success" and Error" is not triggered.

The post call to "/logout" will result Http status return code 200 with empty respond body which is expected

import { httpClient } from angular/common/http;
private http: HttpClient;

this.http.post<any>('/logout', {})
      .subscribe(
      () => {
        console.log("Logout");
      }, error => {
        console.log(error);
      },
      () => {
        console.log("Finally");
      });

It will output "Finally" 100% of time. That means success and error is not triggered at all.

Is there possibilities that either success and error not trigger. And clearly the http status code response is 200 OK.

Update: The answer that @meriton provided work great.

Zeo
  • 115
  • 1
  • 14
  • Either success or error will trigger regardless of the status. If there server doesn't respond the browser will timeout the request (also an error) – Drenai Nov 08 '21 at 07:37
  • But it doesn't trigger Either Success or Error that is what puzzling me. – Zeo Nov 08 '21 at 15:10
  • @Drenai Sorry about that. My bad – Zeo Nov 08 '21 at 15:43

2 Answers2

3

Observable, in general, are not required to complete or error. They may remain live, and continue to emit values, forever.

However, Observable returned by HttpClient are guaranteed to terminate with either success or error (though the error may take a few minutes in case of a timeout) according to the HTTP status of the response. The presence of absence of a body does not affect this. If the request is successful, the observable will emit exactly one value: the response body (or null if the response body is absent).

I can not reproduce your claim that "success or error is not triggered at all". May you have misunderstood what the callbacks mean? When you provide three callbacks to subscribe, they are, in order:

  • the next callback, which receives emitted values
  • the error callback, which notifies that the Observable has aborted due to an error
  • the complete callback, which notifies that the Observable has completed successfully

The danger of mixing up callbacks is one reason why the RXJS team has deprecated passing several callbacks as separate arguments to subscribe in RXJS 8. The future proof way to write your code would be:

this.http.post<any>('/logout', {}).subscribe({
  complete: () => {
    console.log("Logout successful")
  },
  error: (error) => {
    console.log(error);
  }
});

BTW, none of these callbacks mean "finally", as in the finally clause of a try-statement, which is executed both in case of success and error. If you want to do something irrespective of whether the Observable completed successfully or failed with an error, you could use the finalize operator.

meriton
  • 68,356
  • 14
  • 108
  • 175
  • This isn't correct. The OP has three callbacks, and didn't say they're not being invoked, but is asking if there's any situation in which they wouldn't be invoked. The 'finally' text is just output to console, but it's still the `complete` callback – Drenai Nov 08 '21 at 07:46
  • @Drenai the answer provides a clear description about what is expected from the Observable returned by the HttpClient: "However, Observable returned by HttpClient are guaranteed to terminate with either success or error (though the error may take a few minutes in case of a timeout) according to the HTTP status of the response. The presence of absence of a body does not affect this." There are just some more details about the why and a better approach. IMO this answer is not incorrect. – Jonathan Stellwag Nov 08 '21 at 09:16
  • 1
    @Drenai: Thanks for pointing that out. I believed OP when he said the callbacks were not invoked, and the `Observable` skipping the emission in the absence of a body seemed the most logical explanation, but you're correct that the `Observable` emits `null` in this case. I have edited to fix this. I have also rephrased my comment about the "finally", it is clearer now? I just meant to ensure that OP understood that `complete` is only invoked in case of *successful* completion, but not in case of abnormal termination, since OP logging completion as "finally" is really misleading. – meriton Nov 08 '21 at 16:29
1
  1. http library success depends on Status:200, it does not require message.body to be present

  2. Example code of using RXJS pipe flow, where you can control the flow by capturing success & error, controlling timeout. It also demonstrates how you can use .subscribe() method as classic Finally

Example RXJS Flow:

 this.http
      .post<any>('/logout',{})
      .pipe(
        map(() => {                 // OK
          return { success: true, err: null }; 
        }),
        timeout(10000),             // CONTROL TIMEOUT
        catchError((e) => {         // IN CASE OF ERROR
          return of({success: false, err:e});
        })
      )
      .subscribe((result) => {        // FINALLY here
        if (result.success) {
          console.log('Logged out successfully');
        } else {
          console.log('Logout failed', result.err); 
        }
      });
IMDB
  • 74
  • 4
  • Can you give us an explanation what your code does and how it belongs to the question? – Jonathan Stellwag Nov 08 '21 at 09:17
  • The question isn't 100% clear. Going by the summary in the question: "It wont trigger either "success" call (because no data come back)?, and error not trigger to." Zeo is clearly concerned success will NOT be triggered because he believes lack of Body response from HTTP equates to success not being fired. Also his question is filed under RXJS. This code gives him an exact flow matching classic Subscribe with (success, error, finally) to RXJS flow. It also clearly demonstrates capture of success even w/ empty BODY. Plus alternative to 'finally' w/ use of subscribe() – IMDB Nov 08 '21 at 13:57
  • Your example is using `get`, question is about `post` with empty response body – Drenai Nov 08 '21 at 17:13
  • updated it to post, it's the same approach – IMDB Nov 08 '21 at 17:18