#Higher order Observable issue

4 messages · Page 1 of 1 (latest)

exotic pilot
#

I have this code, I guess the switchMap unsubscribes from the one that the map returns; problem is every 2nd click the form submission refreshes the page, so how can I fix it:

import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  ElementRef,
  inject,
  viewChild,
} from '@angular/core';
import { fromEvent, map, switchMap } from 'rxjs';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent implements AfterViewInit {
  private _httpClient = inject(HttpClient);
  private _formRef = viewChild<ElementRef<HTMLFormElement>>('form');

  ngAfterViewInit(): void {
    const formRef = this._formRef()!;

    const loginFormSubmit = fromEvent(formRef.nativeElement, 'submit').pipe(
      map(event => {
        event.preventDefault();

        const formData = new FormData(formRef.nativeElement);
        const username = formData.get('username') as string;
        const password = formData.get('password') as string;

        return {
          username,
          password,
        };
      }),
      switchMap(({ username, password }) =>
        this._httpClient.post(
          'https://dummyjson.com/auth/login',
          JSON.stringify({ username, password })
        )
      )
    );

    loginFormSubmit.subscribe({
      next: response => {
        console.log('Login response:', response);
      },
      error: err => {
        console.error('Login error:', err);
      },
    });
  }
}
exotic pilot
#

If I put switchMap(() => of('whatever')) instead of that API call, the it still works - so the HTTP call is somehow connected to my problem?

#

If I simulate slow network, it works as intended (unsubscribing from the API requests and subscribing to the next one, because I am spamming the submit button) until the response fails (no idea why API returns an error saying {"message":"Username and password required"}, that's another issue). So when the API returns a problem, then the preventDefault stops working.

#

So this switchMap code works as intended:

      switchMap(({ username, password }) =>
        this._httpClient
          .post(
            'https://dummyjson.com/auth/login',
            JSON.stringify({ username, password })
          )
          .pipe(
            catchError(error => {
              return of(error);
            })
          )
      )

Can anyone explain why?

I tried swapping the of(error) with throwError(() => new Error(error)), but then the original issue with preventDefault stops working again

It seems that practically the code works as intended, but the console log says Login response: even though the message is the error part about missing username and password - so I guess it's gracefully handled. So is it not possible to have the error in the console whilst handling it?