首页 > 解决方案 > NGRX 效果/Firebase (Firestore) 错误

问题描述

我有一个带有 ngrx 和 firebase 的 angular 6 应用程序,并设置了我的商店和服务来执行基本的 crud 操作。

一切似乎都运行良好,即我可以添加、编辑、删除条目。但是,我正在尝试执行成功操作,但它似乎永远不会执行该操作,而且我不知道如何捕获错误。

效果中的以下几行似乎从未执行过,我也没有收到任何错误。

.pipe(
              map(() => new tasksActions.RemoveTaskSuccess(task)),
              catchError(error => of(new tasksActions.RemoveTaskFail(error)))
            );

我试图调试,但代码只是不返回。

影响

 @Effect()
      removeTask$ = this.actions$.ofType(tasksActions.REMOVE_TASK).pipe(
        map((action: tasksActions.RemoveTask) => action.payload),
        switchMap(task => {
          return this.fss
            .delete('tasks/' + task.id)
            .pipe(
              map(() => new tasksActions.RemoveTaskSuccess(task)),
              catchError(error => of(new tasksActions.RemoveTaskFail(error)))
            );
        })
      );

服务

delete<T>(ref: DocPredicate<T>): Observable<any> {
    return new Observable(observer => {
      this.doc(ref).delete();
    });
  }

行动

import { Action } from '@ngrx/store';
import { Board } from '../../models/task.model';

export const LOAD_TASKS = '[Tasks]: Load Tasks';
export const LOAD_TASKS_FAIL = '[Tasks]: Load Tasks Fail';
export const LOAD_TASKS_SUCCESS = '[Tasks]: Load Tasks Success';
export const CREATE_TASK = '[Tasks]: Create Task';
export const CREATE_TASK_FAIL = '[Tasks]: Create Task Fail';
export const CREATE_TASK_SUCCESS = '[Tasks]: Create Task Success';
export const UPDATE_TASK = '[Tasks] Update ';
export const UPDATE_TASK_FAIL = '[Tasks] Update  Fail';
export const UPDATE_TASK_SUCCESS = '[Tasks] Update  Success';
export const REMOVE_TASK = '[Tasks] Remove Task ';
export const REMOVE_TASK_FAIL = '[Tasks] Remove Task  Fail';
export const REMOVE_TASK_SUCCESS = '[Tasks] Remove Task  Success';

export class LoadTasks implements Action {
  readonly type = LOAD_TASKS;
}

export class LoadTasksFail implements Action {
  readonly type = LOAD_TASKS_FAIL;
  constructor(public payload: any) {}
}

export class LoadTasksSuccess implements Action {
  readonly type = LOAD_TASKS_SUCCESS;
  constructor(public payload: Board[]) {}
}

export class CreateTask implements Action {
  readonly type = CREATE_TASK;
  constructor(public payload: Board) {}
}

export class CreateTaskFail implements Action {
  readonly type = CREATE_TASK_FAIL;
  constructor(public payload: any) {}
}

export class CreateTaskSuccess implements Action {
  readonly type = CREATE_TASK_SUCCESS;
  constructor(public payload: Board) {}
}

export class UpdateTask implements Action {
  readonly type = UPDATE_TASK;
  constructor(public payload: Board) {}
}

export class UpdateTaskFail implements Action {
  readonly type = UPDATE_TASK_FAIL;
  constructor(public payload: any) {}
}

export class UpdateTaskSuccess implements Action {
  readonly type = UPDATE_TASK_SUCCESS;
  constructor(public payload: Board) {}
}

export class RemoveTask implements Action {
  readonly type = REMOVE_TASK;
  constructor(public payload: Board) {}
}

export class RemoveTaskFail implements Action {
  readonly type = REMOVE_TASK_FAIL;
  constructor(public payload: any) {}
}

export class RemoveTaskSuccess implements Action {
  readonly type = REMOVE_TASK_SUCCESS;
  constructor(public payload: Board) {}
}

export type TasksAction =
  | LoadTasks
  | LoadTasksFail
  | LoadTasksSuccess
  | CreateTask
  | CreateTaskFail
  | CreateTaskSuccess
  | UpdateTask
  | UpdateTaskFail
  | UpdateTaskSuccess
  | RemoveTask
  | RemoveTaskFail
  | RemoveTaskSuccess;

减速器

import * as fromTasks from '../actions/tasks.actions';
import { Board } from '../../models/task.model';
// import { reducers } from '../../../../../../store/reducers/index';

export interface TaskState {
  entities: { [id: string]: Board };
  loaded: boolean;
  loading: boolean;
}

export const initialState: TaskState = {
  entities: {},
  loaded: false,
  loading: false
};

export function reducer(state = initialState, action: fromTasks.TasksAction): TaskState {
  switch (action.type) {
    case fromTasks.LOAD_TASKS: {
      return {
        ...state,
        loading: true
      };
    }

    case fromTasks.LOAD_TASKS_FAIL: {
      return {
        ...state,
        loading: false,
        loaded: false
      };
    }

    case fromTasks.LOAD_TASKS_SUCCESS: {
      const tasks = action.payload;
      const entities = tasks.reduce(
        // tslint:disable-next-line:no-shadowed-variable
        (entities: { [id: string]: Board }, task: Board) => {
          return {
            ...entities,
            [task.id]: task
          };
        },
        {
          ...state.entities
        }
      );
      return {
        ...state,
        loading: false,
        loaded: true,
        entities
      };
    }

    // If update or create
    case fromTasks.UPDATE_TASK_SUCCESS:
    case fromTasks.CREATE_TASK_SUCCESS: {
      const task = action.payload;
      const entities = {
        ...state.entities,
        [task.id]: task
      };

      return {
        ...state,
        entities
      };
    }

    case fromTasks.REMOVE_TASK_SUCCESS: {
      const task = action.payload;
      const { [task.id]: removed, ...entities } = state.entities;

      return {
        ...state,
        entities
      };
    }
  }
  return state;
}

export const getTasksEntities = (state: TaskState) => state.entities;
export const getTasksLoading = (state: TaskState) => state.loading;
export const getTasksLoaded = (state: TaskState) => state.loaded;

标签: angularfirebaserxjsgoogle-cloud-firestorengrx

解决方案


您需要捕获服务部分的错误,映射结果并捕获外部 observable 的错误。Firestore delete 返回一个 promise,将其转换为 observable 并捕获错误:

delete<T>(ref: DocPredicate<T>): Observable<any> {
    // RxJS v5 'fromPromise' is changed to 'from'
    return from(this.doc(ref).delete()).pipe(
        catchError(error => throwError(error))
    )
)

推荐阅读