从RESTful分页集合中观察

时间:2017-06-12 07:38:45

标签: json rest angular rxjs hateoas

一方面,我有一个RESTful HAL HATEOAS集合,如下所示:

{
    "page": 1,
    "limit": 10,
    "pages": 18,
    "total": 174,
    "_links": {
        "self":  { "href": "/users?page=1&limit=10" },
        "first": { "href": "/users?page=1&limit=10" },
        "last":  { "href": "/users?page=18&limit=10" },
        "next":  { "href": "/users?page=2&limit=10" }
    },
    "_embedded": {
        "users": [
            {
                "name": "bob",
                "_links": { "self": { "href": "/users/1" } }
            },
            ...
        ]
     }
}

另一方面,我有一个Angular 2应用程序。

public getUsers(uri: string = this.baseURI): Observable<User> {
  return this.http.get(uri)
    .map(res => res.json()._embedded.users as User[])
    .flatMap(d => d) // Transform the flux of arrays in flux of users
    .catch(this.handleError);
} // Get only the 10th first users

我尝试做的事情有一个可观察的用户,会在_links.next != null

时追加数据

修改后的服务

public getUsers(uri: string = this.baseURI): Observable<User> {
  return this.http.get(uri)
    .do(res => {
        const uri = JSON.parse(res._body)._links.next.href;
        this.nextUri = uri ? uri : null;
     })
    .map(res => res.json()._embedded.users as User[])
    .flatMap(d => d) // Transform the flux of arrays in flux of users
    .catch(this.handleError);
} 

递归函数

loadAll(uri: string) {
    read(uri)
      .subscribe(
        user => {
          this.stockedUsers.push(user);
        },
        error => console.log(error),
        () => {
          if (this.nextUri) {
            this.loadAll(this.nextUri);
          }
        }
      );
}

有人知道如何正确实现这一目标吗? 我想保留RxJS通量的优势。

UPDATE / ANSWER 傻我!我想我回答了自己。也许这会对其他人有所帮助:

public read(uri: string = this.baseURI): Observable<User> {
  return Observable.create(observer => this.iteratePages(observer, uri));
}

private iteratePages(observer: Observer<User>, uri): void {
  if (uri == null) { return observer.complete(); }
  this.http.get(uri).subscribe(res => {
    const data = res.json();
    for (const user of data._embedded.users) {
      observer.next(user as User);
    }
    const nextUri = (data._links && data._links.next) ? data._links.next.href : null;
    this.iteratePages(observer, nextUri);
  });
}

0 个答案:

没有答案