angular - NGRX + Resolver not working: Component seems to be loading before action is done dispatching
问题描述
I'm trying to fetch the data from a route and load the data into my state before showing my detail component, and for this reason I have created a resolver. My get request is working, that I know, but it seems as if the api call is done after the component is loaded.
@Injectable()
export class WorkOrderDetailResolver implements Resolve<WorkOrder> {
constructor(
private store: Store<fromApp.AppState>
) { }
waitForWorkOrderDataToLoad(route, state) {
this.store.dispatch(new WorkOrderActions.FetchWorkOrderFromAPIByID(+route.params['id']));
return this.store.select(state => state.workOrder.workOrderDetails).pipe(take(1));
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<WorkOrder> | Promise<WorkOrder> | WorkOrder {
return this.waitForWorkOrderDataToLoad(route, state);
}
}
These are my routes where I clearly apply the resolver to the WorkOrderDetailsComponent
const workOrderRoutes: Routes = [
{
path: 'workorders',
component: WorkOrderComponent,
children: [
{ path: 'new', component: WorkOrderEditComponent },
{ path: 'list', component: WorkOrderListComponent },
{ path: ':id', component: WorkOrderDetailComponent, resolve: { workOrderDetails: WorkOrderDetailResolver } },
{ path: ':id/edit', component: WorkOrderEditComponent }
]
}
];
And finally here is the code for the WorkOrdersDetailComponent:
@Component({
selector: 'app-work-order-detail',
templateUrl: './work-order-detail.component.html',
styleUrls: ['./work-order-detail.component.css']
})
export class WorkOrderDetailComponent implements OnInit {
private id: number;
workOrder: WorkOrder;
workOrderState: Observable<{workOrders: WorkOrder[]}>;
constructor(private route: ActivatedRoute,
private router: Router,
) { }
ngOnInit() {
console.log(this.route.snapshot.data);
this.workOrder = this.route.snapshot.data.workOrderDetails;
}
onEditWorkOrder() {
this.router.navigate(['edit'], {relativeTo: this.route});
}
}
To explain what my goal is with the code in the resolver is, Dispatch the action for fetching an workOrder by id from my API and store it the state (this works), once this is done, and ONLY after it is done, return an observable of the workOrder that I stored in the state and load the WorkOrderDetailComponent.
The error I the view cannot read value of null for the workOrder the first time the route is loaded, but what then happens is that if I navigate away and back to the page, the workOrder is not null anymore. So my guess is the resolver is for some reason not doing it's magic before the component is loaded? What I want is for the resolver to return Observable<{WorkOrder]> so that I can load it asynch in the view.
Also, it could very much be just an issue with me not using the rxjs operators properly for this, I'm having quite a hard time grasping how observables work and how these operators should be chained. If that is the case, please enlighten me of what is wrong and why.
Thanks!
解决方案
您应该等到选择器返回一个值
this.store.pipe(
select(state => state.workOrder.workOrderDetails),
filter(details => !!details),
take(1)
);
请注意,我也在使用select
运算符而不是select
商店中的方法。这是因为select
store 上的方法已被弃用,将来将被删除。
推荐阅读
- javascript - jQuery filter() 用于已加载数据的国家/州/城市列表(无 ajax 调用)
- html - 如何将绝对元素居中在另一个绝对元素中,可用于旋转和动画目的
- c++ - 数学 - 返回索引添加先前跳过的索引的函数
- angularjs - 在 AngularJS Material 中首次单击时显示自动完成下拉菜单
- node.js - 如何使用javascript“启动更多这样”ec2-instances
- c# - C# Word 互操作 - 打开没有转换提示的 .pdf
- typescript - TypeORM 属性可以为空,但收到“不能为不可为空的字段 xx 返回 null”
- python - 限制并发线程数
- python - 用scikit learn,如何在fit_predict中使用predict_proba?
- java - 如何在禁用自动计算的情况下在 ValueAxis 上设置边距?