无法将订阅的可观察对象作为字符串放入集合中
Cannot put subscribed observable into collection as a string
我是 typescript 和 javascript 的新手,我真的很难搞清楚集合和文件 io 是如何工作的。我正在尝试从 json 文件中获取数据,尽管当我将其放入集合中时该集合没有数据,但我成功了。
代码如下:
为我服务class:
private configuration = "../../assets/Configurations/testConfiguration.json";
constructor(private http: HttpClient) {}
getBlogs(blog: string): Observable<IBlogPost[]> {
return this.http.get<IBlogPost[]>(blog);
}
getConfigurations() {
var configurationsData = [];
this.http.get(this.configuration).subscribe(data => {
configurationsData.push(data);
console.log(data);
// This will work and will print all the paths
});
//This will not work and will not print them, like if the collection is empty
configurationsData.forEach(x => console.log(x));
return configurationsData;
}
我在哪里获得我的服务 class 注入:
blogs: IBlogPost[] = [];
private blogsPaths: string[] = [];
errorMessage = "";
constructor(private appUtilityService: AppUtilityServices) {}
ngOnInit() {
//This will not work, blogsPaths will not received the full collection as it should
this.blogsPaths = this.appUtilityService.getConfigurations();
this.blogsPaths.forEach(blogPath =>
this.appUtilityService.getBlogs(blogPath).subscribe(
b =>
b.forEach(blog => {
this.blogs.push(blog);
}),
error => (this.errorMessage = <any>error)
)
);
}
testConfiguration.json:
[
"../../assets/BlogPosts/testBlog1.json",
"../../assets/BlogPosts/testBlog2.json"
]
如果您包含有关集合如何在 javascript 中工作以及如何正确 return 它们的好教程,则可获赠
在 getConfigurations
中,您正在调用异步 http 请求。所以这很正常, configurationsData
在 subscribe
方法之外是空的。
在这里,我使用强大的RxJS来简化代码并避免使用
Array.push
和嵌套 subscribe()
.
1) 获取数据的基本异步服务方法
所以 getConfigurations
应该 return 一个 Observable
:
getConfigurations(): Observable<string[]> {
return this.http.get<string[]>(this.configuration);
}
而且 getBlogs
应该 return 一个 Observable
:
getBlogs(blogsPath: string): Observable<BlogPost[]> {
return this.http.get<BlogPost[]>(blogsPath);
}
在这里,为了尊重Angular最佳实践,我删除了每个界面开头的I
,所以BlogPost
.
2) 这就是RxJS的神奇之处
然后,您的服务中有另一种方法可以检索 Observable
篇博文,它应该如下所示:
getBlogPosts(): Observable<BlogPost[]> {
return this.getConfigurations().pipe(
mergeAll(),
concatMap(blogsPath => this.getBlogs(blogsPath)),
concatAll(),
toArray()
)
}
这意味着,检索博客路径的所有集合,对于每个路径数组,对于每个路径,获取博客帖子,然后 return 所有帖子的唯一数组。
最后,在您的组件中,您通过订阅调用 getBlogPosts
:
ngOnInit() {
this.service.getBlogPosts().subscribe(blogs => {
...do something with your blogs array.
});
}
或者在模板中使用 async
管道更好:
.ts 文件:
blogs$: Observable<BlogPost[]>;
...
this.blogs$ = this.appService.getBlogPosts();
.html 文件:
<ul *ngIf="blogs$ | async as blogs">
<li *ngFor="let blog of blogs">
#{{ blog.id }} - {{ blog.title }}
</li>
</ul>
在 Stackbliz 上查看我的 full demonstration of this RxJS alternative。
原来是这样,是的真的...
这里我做得很好:
初始化时:
this.appUtilityService.getConfigurations().subscribe(
b =>
b.forEach(x => {
this.appUtilityService.getBlogs(x).subscribe(
b =>
b.forEach(blog => {
this.blogs.push(blog);
}),
error => (this.errorMessage = <any>error)
);
}),
error => (this.errorMessage = <any>error)
);
AppUtilityService:
getBlogs(blog: string): Observable<IBlogPost[]> {
return this.http.get<IBlogPost[]>(blog);
}
getConfigurations(): Observable<string[]> {
return this.http.get<string[]>(this.configuration);
}
让它变得非常漂亮:
ngOnInit() {
this.initializeBlog();
}
private initializeBlog(): void {
this.appUtilityService.getConfigurations().subscribe(
b =>
b.forEach(x => {
this.appUtilityService.getBlogs(x).subscribe(
b =>
b.forEach(blog => {
this.blogs.push(blog);
}),
error => (this.errorMessage = <any>error)
);
}),
error => (this.errorMessage = <any>error)
);
}
我是 typescript 和 javascript 的新手,我真的很难搞清楚集合和文件 io 是如何工作的。我正在尝试从 json 文件中获取数据,尽管当我将其放入集合中时该集合没有数据,但我成功了。
代码如下:
为我服务class:
private configuration = "../../assets/Configurations/testConfiguration.json";
constructor(private http: HttpClient) {}
getBlogs(blog: string): Observable<IBlogPost[]> {
return this.http.get<IBlogPost[]>(blog);
}
getConfigurations() {
var configurationsData = [];
this.http.get(this.configuration).subscribe(data => {
configurationsData.push(data);
console.log(data);
// This will work and will print all the paths
});
//This will not work and will not print them, like if the collection is empty
configurationsData.forEach(x => console.log(x));
return configurationsData;
}
我在哪里获得我的服务 class 注入:
blogs: IBlogPost[] = [];
private blogsPaths: string[] = [];
errorMessage = "";
constructor(private appUtilityService: AppUtilityServices) {}
ngOnInit() {
//This will not work, blogsPaths will not received the full collection as it should
this.blogsPaths = this.appUtilityService.getConfigurations();
this.blogsPaths.forEach(blogPath =>
this.appUtilityService.getBlogs(blogPath).subscribe(
b =>
b.forEach(blog => {
this.blogs.push(blog);
}),
error => (this.errorMessage = <any>error)
)
);
}
testConfiguration.json:
[
"../../assets/BlogPosts/testBlog1.json",
"../../assets/BlogPosts/testBlog2.json"
]
如果您包含有关集合如何在 javascript 中工作以及如何正确 return 它们的好教程,则可获赠
在 getConfigurations
中,您正在调用异步 http 请求。所以这很正常, configurationsData
在 subscribe
方法之外是空的。
在这里,我使用强大的RxJS来简化代码并避免使用
Array.push
和嵌套 subscribe()
.
1) 获取数据的基本异步服务方法
所以 getConfigurations
应该 return 一个 Observable
:
getConfigurations(): Observable<string[]> {
return this.http.get<string[]>(this.configuration);
}
而且 getBlogs
应该 return 一个 Observable
:
getBlogs(blogsPath: string): Observable<BlogPost[]> {
return this.http.get<BlogPost[]>(blogsPath);
}
在这里,为了尊重Angular最佳实践,我删除了每个界面开头的I
,所以BlogPost
.
2) 这就是RxJS的神奇之处
然后,您的服务中有另一种方法可以检索 Observable
篇博文,它应该如下所示:
getBlogPosts(): Observable<BlogPost[]> {
return this.getConfigurations().pipe(
mergeAll(),
concatMap(blogsPath => this.getBlogs(blogsPath)),
concatAll(),
toArray()
)
}
这意味着,检索博客路径的所有集合,对于每个路径数组,对于每个路径,获取博客帖子,然后 return 所有帖子的唯一数组。
最后,在您的组件中,您通过订阅调用 getBlogPosts
:
ngOnInit() {
this.service.getBlogPosts().subscribe(blogs => {
...do something with your blogs array.
});
}
或者在模板中使用 async
管道更好:
.ts 文件:
blogs$: Observable<BlogPost[]>;
...
this.blogs$ = this.appService.getBlogPosts();
.html 文件:
<ul *ngIf="blogs$ | async as blogs">
<li *ngFor="let blog of blogs">
#{{ blog.id }} - {{ blog.title }}
</li>
</ul>
在 Stackbliz 上查看我的 full demonstration of this RxJS alternative。
原来是这样,是的真的...
这里我做得很好:
初始化时:
this.appUtilityService.getConfigurations().subscribe(
b =>
b.forEach(x => {
this.appUtilityService.getBlogs(x).subscribe(
b =>
b.forEach(blog => {
this.blogs.push(blog);
}),
error => (this.errorMessage = <any>error)
);
}),
error => (this.errorMessage = <any>error)
);
AppUtilityService:
getBlogs(blog: string): Observable<IBlogPost[]> {
return this.http.get<IBlogPost[]>(blog);
}
getConfigurations(): Observable<string[]> {
return this.http.get<string[]>(this.configuration);
}
让它变得非常漂亮:
ngOnInit() {
this.initializeBlog();
}
private initializeBlog(): void {
this.appUtilityService.getConfigurations().subscribe(
b =>
b.forEach(x => {
this.appUtilityService.getBlogs(x).subscribe(
b =>
b.forEach(blog => {
this.blogs.push(blog);
}),
error => (this.errorMessage = <any>error)
);
}),
error => (this.errorMessage = <any>error)
);
}