Angular 我想在ngOnInit(){}中的第二个方法内的一个方法中使用.subscribe的结果

Angular 我想在ngOnInit(){}中的第二个方法内的一个方法中使用.subscribe的结果,angular,observable,subscribe,ngoninit,Angular,Observable,Subscribe,Ngoninit,我有一个方法,它使用一个服务来获取一个图书列表,我需要第二个方法,它使用图书列表通过id过滤来获取一本书。这两个方法在同一组件的“ngOnInit”中调用。我得到的是第二种方法在得到结果之前使用图书列表 我通过在.subscribe的结果中调用第一个方法中的第二个方法修复了这个问题,然后只调用ngOnInit中的第一个方法。我觉得这个解决方案不太令人满意,我想要一个更普遍、更有组织的方式 导出类BookComponent实现OnInit{ 公共图书:图书[]; 公共图书:图书; 公共id; 公共

我有一个方法,它使用一个服务来获取一个图书列表,我需要第二个方法,它使用图书列表通过id过滤来获取一本书。这两个方法在同一组件的“ngOnInit”中调用。我得到的是第二种方法在得到结果之前使用图书列表

我通过在.subscribe的结果中调用第一个方法中的第二个方法修复了这个问题,然后只调用ngOnInit中的第一个方法。我觉得这个解决方案不太令人满意,我想要一个更普遍、更有组织的方式

导出类BookComponent实现OnInit{
公共图书:图书[];
公共图书:图书;
公共id;
公共分公司;
构造函数(private-activatedRoute:activatedRoute,private-router:router,private-bookService:bookService){}
getBooks(){
此.bookService.getBooks()已订阅(
结果=>{
这就是结果;
}
);
}
findById(){
this.sub=this.activatedRoute.paramMap.subscribe(params=>{
控制台日志(params);
this.id=params.get('id');
this.book=this.books.find(a=>a.id==this.id);
});
}
恩戈尼尼特(){
这个。getbooks();
this.findById();
}
}
以下是我得到的错误:

 ERROR TypeError: Cannot read property 'find' of undefined
试试这个

findById() {
this.sub = this.activatedRoute.paramMap.subscribe(params => {
  console.log(params);
  this.id = params.get('id');
  this.book = this.books.find(a => a.id == this.id);
});
}


ngOnInit() {
  this.books = [];
  this.getbooks();
  this.findById();
}

这是因为书本没有初始化。由于您同时运行两个异步函数,因此不能保证在调用
findById()
之前,
books
的内容是由
getBooks()
初始化的

您可以通过将对
findById()
的调用放在对
getBooks()
的调用中来避免此问题。这种情况会导致订阅地狱(多个嵌套订阅),但可以通过使用rxjs来清除

在下面相应地重新排列了您的原始代码

导出类BookComponent实现OnInit{
公共图书:图书[];
公共图书:图书;
公共id;
公共分公司;
构造函数(private-activatedRoute:activatedRoute,private-router:router,private-bookService:bookService){}
恩戈尼尼特(){
这个。getbooks();
}
getBooks(){
此.bookService.getBooks()已订阅(
结果=>{
这就是结果;
this.findById()
}
);
}
findById(){
this.sub=this.activatedRoute.paramMap.subscribe(params=>{
控制台日志(params);
this.id=params.get('id');
this.book=this.books.find(a=>a.id==this.id);
});
}
}

你的直觉是正确的,你不应该试图在订阅中调用订阅。。。您应该使用更高阶的可观测数据来实现这一目标,并确保在需要的地方获得所有可观测数据。在这种情况下,您希望使用CombineTest:

ngOnInit() {
  this.sub = combineLatest(this.bookService.getBooks(), this.activatedRoute.paramMap)
               .subscribe(([books, params]) => }
                 this.books = books;
                 this.id = params.get('id');
                 this.book = this.books.find(a => a.id == this.id);
               });
}

现在,订阅回调将在任何一个可观察流发出的时候运行,但只有在两个流发出至少一次后才运行。其余的不用了。在这种情况下,我假设getBooks()只会发出一次,但是如果用户导航到不同的图书ID,paramMap可能会再次发出。

这可以防止未定义的错误,但对于解决未定义的原因(或者现在的
[]
)这一根本问题没有任何作用。多亏了这个想法,它实际上可以工作,但只能进行第二次尝试,第一次尝试时,当我第一次路由到一本书并指定一个特定的“id”时,它不起作用…感谢您的回复,这实际上是我描述的解决方案,我不喜欢的解决方案,因为这样getBooks()不仅可以获取书,还可以应用id过滤。。。这就是为什么我想要一种更有条理的方式。你可以使用rxjs来实现这一点,但它的工作方式与标准TS不同。有关更多信息,请参阅。我会说,可能从参数中获取id,然后在调用http时使用它谢谢你解释得很好的回答,我喜欢你的想法,但也考虑了一些代码行将如何重复,因为我真正想要的是一个单独的方法,可以获取书籍,而不是重复使用结果而不重新获取它们,可能/可能通过其他方法,如findById。。。