#High WTFs/min ?

8 messages · Page 1 of 1 (latest)

novel wolf
#

I was wondering if there was a better way to do the loading ? Or would I always have to set it up like this for every component that would need it ?

protected loadingState = signal<LoadingState>({
    isLoading: false,
    error: undefined,
    successMessage: '',
  });

  verifyEmail() {
    console.log('Verifying email', this.otp.value);
    this.loadingState.update((state) => ({ ...state, isLoading: true }));
    const user = this.#userService.getUserInfo();
    const otp = this.otp.value
    if (otp.length === 6) {
      console.log('User', user);
      this.#authService
        .verifyEmail({ code: otp, email: user.email })
        .pipe(
          tap((loggedInUser) => {
            this.#userService.updateUser(loggedInUser);
            this.loadingState.set({
              isLoading: false,
              successMessage: 'Verification successful',
              error: undefined,
            });
            this.#authService.updateAuthStatus()
            this.countDownTimer = '00:00'
            this.#router.navigate(['/settings'], { replaceUrl: true })

          }),
          catchError((err) => {
            this.loadingState.set({
              isLoading: false,
              successMessage: '',
              error: getErrorMessage(err),
            });
            return EMPTY;
          }),
          takeUntilDestroyed(this.#destroyRef)
        )
        .subscribe();
    }
  }
hard mistBOT
#

Hi @novel wolf, please do not post pictures/screenshots of code (especially photos of a physical screen). Screenshots are more difficult to read compared to code in a codeblock, and they do not allow people answering to quickly copy and adjust your code to provide you with an answer.

For copy/pasting code in a discord post, you can use the following snippet to have your code placed in a codeblock with syntax highlighting. Replace ts with the language you are copying (i.e. html, js, css, etc)

```ts
// your code goes here
```

See #how-to-get-help for more tips on how to ask code related questions in this server.

novel wolf
#

Oh my bad

tall aspen
#

Why dont you directly use toSignal method, and @if(){} in template. While toSignal value is null @if(verifyEmailSignal() !== null){ // data state}@else{ // Loading state.. } Do same for error signal new variable. What you say?

crisp ibex
#

Here is my proposal:

I would recommend creating some service, like LoadingService, which will contain your LoadingState and it's logic.

Then you can access loadingState from service and modify it's value easily by calling some methods exposed by that service.

Do not inject it at root level, inject it in component by providing it in providers array, so each component, which shall have such functionality, will have it's own instance.

I also refactored the code, which you have provided, it works the same. I just seperated logic into different smaller functions.

Now, for the code itself:

#
  • Component code:
loadingService: LoadingService = inject(LoadingService);

  verifyEmail() {
    this.setLoadingToTrue();

    const user = this.getUser();
    const otp = this.getOtpValue();

    console.log('Verifying email', otp);
    if (this.isOtpValueValid()) {
      console.log('User', user);

      this.#authService
        .verifyEmail({ code: otp, email: user.email })
        .pipe(
          tap((loggedInUser) => this.updateUser(loggedInUser)),
          tap(() => this.updateAuthStatus()),
          tap(() => this.resetLoadingError()),
          tap(() => this.resetCountDownTimer()),
          tap(() => this.setLoadingToFalse()),
          tap(() => this.navigateToSettings()),
          catchError((err) => {
            this.resetSuccessMessage();
            this.updateErrorMessageByError(err);
            this.setLoadingToFalse();
            return EMPTY;
          }),
          takeUntilDestroyed(this.#destroyRef)
        )
        .subscribe();
    }
  }

  getUser() {
    return this.#userService.getUserInfo();
  }

  getOtpValue() {
    return this.otp.value;
  }

  isOtpValueValid() {
    return this.getOtpValue().length === 6;
  }

  updateUser(user: any) {
    this.#userService.updateUser(user);
  }

  updateErrorMessageByError(error: any) {
    this.loadingService.updateErrorMessageByError(error);
  }

  updateAuthStatus() {
    this.#authService.updateAuthStatus();
  }

  setLoadingToTrue() {
    this.loadingService.setLoadingToTrue();
  }

  setLoadingToFalse() {
    this.loadingService.setLoadingToFalse();
  }

  setLoadingMessageToSuccess() {
    this.loadingService.updateSuccessMessage('Verification successful');
  }

  resetSuccessMessage() {
    this.loadingService.resetSuccessMessage();
  }

  resetLoadingError() {
    this.loadingService.resetError();
  }

  resetCountDownTimer() {
    this.countDownTimer = '00:00';
  }

  navigateToSettings() {
    this.#router.navigate(['/settings'], { replaceUrl: true });
  }
#
  • Service code:
import { Injectable, Signal, signal } from '@angular/core';
import { LoadingState } from '../interface/loading-state.interface';

@Injectable()
export class LoadingService {
  private _loadingState = signal<LoadingState>({
    isLoading: false,
    errorMessage: null,
    successMessage: null,
  });
  loadingState: Signal<LoadingState> = this._loadingState.asReadonly();

  setLoadingToTrue() {
    this._loadingState.update((state) => ({ ...state, isLoading: true }));
  }

  setLoadingToFalse() {
    this._loadingState.update((state) => ({ ...state, isLoading: false }));
  }

  resetError() {
    this._loadingState.update((state) => ({ ...state, errorMessage: null }));
  }

  resetSuccessMessage() {
    this._loadingState.update((state) => ({ ...state, successMessage: null }));
  }

  updateSuccessMessage(message: string) {
    this._loadingState.update((state) => ({
      ...state,
      successMessage: message,
    }));
  }

  updateErrorMessageByError(error: any) {
    const errorMessage = this.getErrorMessage(error);
    this._loadingState.update((state) => ({
      ...state,
      errorMessage,
    }));
  }

  private getErrorMessage(err: any) {
    return 'some error message';
  }
}
novel wolf