angular - 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;
解决方案
您需要捕获服务部分的错误,映射结果并捕获外部 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))
)
)
推荐阅读
- powershell - PowerShell:将 16MB CSV 导入 PowerShell 变量会创建 >600MB 的 PowerShell 内存使用量
- c++ - 如何在 C++ 中通过多种类型从元组中选择多个元素?
- postgresql-9.5 - 是否可以在不关闭数据库的情况下运行 pg_rewind?
- excel - 阻止 Excel 用户使用 X、最小化和最大化按钮关闭电子表格
- java - 在从片段单击按钮时更改 ViewPager2 内 textview 中的文本
- swift - 单击按钮时如何使进度条增加?迅速
- javascript - 如何将带有分隔符的连接数组拆分为块
- rest - 在 REST API 中处理批量删除
- assembly - 使用 x86 程序集计算 x*log_2(y)
- android-camera - Unity3D:AR 基础 - CameraConfigFilter?