无法将已订阅的Observable作为字符串放入集合中

时间:2019-06-30 15:15:32

标签: javascript angular typescript collections file-io

我是打字稿和JavaScript的新手,而且我很难确定收集和文件io的工作方式。我正在尝试从json文件中获取数据,尽管将其放入集合时,集合中没有数据,但我还是成功地获得了数据。

代码如下:

在我的服务班级:

  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;
  }

我在哪里注入了我的服务课程:

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中使用集合以及如何正确返回它们的好教程,请奖励

2 个答案:

答案 0 :(得分:0)

var fire = turret.Fire(shootTarget + offset); if (!turret.firing && InRange() == true) { StartCoroutine(fire); } 内部,您正在调用异步http请求。因此,在getConfigurations方法之外,configurationsData为空是正常的。

在这里,我正在使用功能强大的RxJS 来简化代码并避免使用 subscribe和嵌套的Array.push

1)获取数据的基本异步服务方法

因此,subscribe()应该返回一个getConfigurations

Observable

并且getConfigurations(): Observable<string[]> { return this.http.get<string[]>(this.configuration); } 也应该返回getBlogs

Observable

在这里,为了尊重Angular的最佳实践,我在每个界面的开头都删除了getBlogs(blogsPath: string): Observable<BlogPost[]> { return this.http.get<BlogPost[]>(blogsPath); } ,所以I

2)这是RxJS的魔力

然后,您的服务中就有另一种方法来检索BlogPost个博客文章,该形式应如下所示:

Observable

这意味着,针对每个路径数组,每个路径检索博客路径的所有集合,获取博客帖子,然后返回所有帖子的唯一数组。

最后,在您的组件内部,您通过订阅呼叫getBlogPosts(): Observable<BlogPost[]> { return this.getConfigurations().pipe( mergeAll(), concatMap(blogsPath => this.getBlogs(blogsPath)), concatAll(), toArray() ) }

getBlogPosts

,或者在模板中使用ngOnInit() { this.service.getBlogPosts().subscribe(blogs => { ...do something with your blogs array. }); } 管道甚至更好:

.ts文件:

async

.html文件:

blogs$: Observable<BlogPost[]>;
...
this.blogs$ = this.appService.getBlogPosts();

在Stackbliz上检查我的full demonstration of this RxJS alternative

推荐阅读medium from Tomas Trajan

答案 1 :(得分:0)

原来是这个,是的……

我在这里很好:

OnInit:

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)
    );
  }