Angular 9 createEffect Наблюдаемый тип Ошибка - PullRequest
0 голосов
/ 03 мая 2020

Я использую официальные руководства, такие как от ngrx . Я хочу создать свой первый объект магазина для auth. Я подумал, что могу лучше понять logi c и улучшить свои навыки, если я начну с logout logi c.

. В качестве нулевого шага я создаю сервис для http-запроса http-auth.service.ts:

import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { throwError, Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

import { environment } from 'environments/environment';
import { RegistrationModel } from 'app/shared/models';
import { TextSuccessModel } from 'app/shared/models/common';

@Injectable()
export class HttpAuthService {
  constructor(private http: HttpClient) {}

  $logout(): Observable<TextSuccessModel> {
    // @FIXME: post request
    return this.http.get(`${environment.apiUrl}/auth/logout`).pipe(
      map((response: TextSuccessModel) => response),
      catchError(this.handleError())
    );
  }

  private handleError<T>() {
    return (error: HttpErrorResponse) => {
      return throwError(error.message || 'Something went wrong');
    };
  }
}

Я создал actions в отдельном файле actions/auth.actions.ts:

import { createAction } from '@ngrx/store';

// logout
export const logout = createAction('[Auth] Logout request');
export const logoutSuccess = createAction('[Auth] Logout Success');
export const logoutError = createAction('[Auth] Logout Fail');

Далее я создал reducer в reducers/auth.reducer.ts:

import { Action, createReducer, on } from '@ngrx/store';

import * as AuthActions from '../actions/auth.actions';

export interface AuthState {
  id: string | null;
  rememberMe: boolean;
}

export const initialState: AuthState = {
  id: null,
  rememberMe: false,
};

export const authReducer = createReducer(
  initialState,
  // logout
  on(AuthActions.logout, (state) => ({
    ...state,
    loading: true,
  })),
  on(AuthActions.logoutSuccess, () => initialState),
  on(AuthActions.logout, () => initialState)
);

export function reducer(state: AuthState | undefined, action: Action) {
  return authReducer(state, action);
}

Далее я создаю Модуль для магазина

import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';
import { RouterModule } from '@angular/router';

import { effects } from './effects';
import { reducers } from './reducers';

@NgModule({
  imports: [
    CommonModule,
    HttpClientModule,
    StoreModule.forFeature('entityCache', reducers),
    EffectsModule.forFeature(effects),
    RouterModule,
  ],
  exports: [StoreModule, EffectsModule],
})
export class AppStoreModule {}

И, наконец, я попытался создать эффект auth.effects.ts:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { exhaustMap, tap, catchError } from 'rxjs/operators';
import { Actions, createEffect, ofType } from '@ngrx/effects';

import { HttpAuthService } from 'app/services/http';
import { TextSuccessModel } from 'app/shared/models/common';

import * as AuthActions from '../actions/auth.actions';

@Injectable()
export class AuthEffects {
  constructor(
    private actions$: Actions,
    private router: Router,
    private httpAuthService: HttpAuthService
  ) {}

  /**
   * LOGOUT
   */
  logout$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(AuthActions.logout),
      exhaustMap(() => {
        return this.httpAuthService.$logout().pipe(
          tap(() => AuthActions.logoutSuccess()),
          catchError(() => of(AuthActions.logoutError()))
        );
      })
    );
  });
}

И vscode пометил мой код как ошибка:

function(): Observable<TextSuccessModel | TypedAction<"[Auth] Logout Fail">>
Argument of type '() => Observable<TextSuccessModel | TypedAction<"[Auth] Logout Fail">>' is not assignable to parameter of type '() => Observable<Action> | ((...args: any[]) => Observable<Action>)'.
  Type 'Observable<TextSuccessModel | TypedAction<"[Auth] Logout Fail">>' is not assignable to type 'Observable<Action> | ((...args: any[]) => Observable<Action>)'.
    Type 'Observable<TextSuccessModel | TypedAction<"[Auth] Logout Fail">>' is not assignable to type 'Observable<Action>'.

Я новичок в angular. Я нашел решение для старых angular версий для создания типов объектов. Но я не понимаю, как это решить. Помогите пожалуйста.

1 Ответ

1 голос
/ 03 мая 2020

Эффект всегда должен возвращать действие (если оно не помечено диспетчерской ошибкой)

Оператор касания не возвращает значение, поскольку оно является пустым. Вы должны использовать карту, чтобы вернуть успешное действие.

  logout$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(AuthActions.logout),
      exhaustMap(() => {
        return this.httpAuthService.$logout().pipe(
          map(() => AuthActions.logoutSuccess()),
          catchError(() => of(AuthActions.logoutError()))
        );
      })
    );
  });
...