Angular 9 createEffect Observable类型为错误。

问题描述 投票:0回答:1

我喜欢官方指南 由ngrx. 我想为我的第一个商店对象创建 auth. 我想,我可以更好地理解逻辑,提高自己的技能,如果我从 logout 逻辑。

作为零步骤,我为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');

接下来,我创建了 reducerreducers/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>'.

I'm new in angular. 我找到了旧版angular创建type对象的解决方案。但我不明白如何解决这个问题。请帮助我。

angular ngrx ngrx-effects
1个回答
1
投票

一个效果应该总是返回一个动作(除非它被标记为dispatch false)。

tap操作符,不返回一个值,因为它是一个void.你应该使用一个map来返回成功的操作。

  logout$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(AuthActions.logout),
      exhaustMap(() => {
        return this.httpAuthService.$logout().pipe(
          map(() => AuthActions.logoutSuccess()),
          catchError(() => of(AuthActions.logoutError()))
        );
      })
    );
  });
© www.soinside.com 2019 - 2024. All rights reserved.