在Angular 5中渲染Observable

时间:2018-02-08 18:44:02

标签: angular async-await angular-ng-if angular-observable

我正在尝试在Angular中渲染 Observable 。我正在向API请求获取一些数据但是,当我尝试渲染它时,浏览器中没有任何内容。

这是服务我用来获取有关1位用户的数据:

export class UserService {

  public _url: string = "https://url/rest/user/";

  constructor(private http: HttpClient) { }

  getUser(id): Observable<IUser>{
    return this.http.get<IUser>(this._url + id)
                  .catch(this.errorHandler);
  }

  errorHandler(error: HttpErrorResponse){
    return Observable.throw(error.message);
  }
}

这是用户组件

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  providers: [ UserService ],
  styleUrls: ['./user.component.css']
})

export class UserComponent implements OnInit {

  public userId;    
  public errorMsg;
  user: IUser;

  constructor(private route: ActivatedRoute, private _userService: 
  UserService) { }

  ngOnInit() {

    let id = parseInt(this.route.snapshot.paramMap.get('id'));
    this.userId = id;

    this._userService.getUser(this.userId)
          .subscribe(data => this.user = data,
                 error => this.errorMsg = error);

  }

}

我用来渲染de User的视图 HTML 是:

<div>
  <h2>{{user?.firstName}} {{user?.lastName}}</h2>
    <dl>
     <dt>Age:</dt>
     <dd>{{user?.age}}</dd>

     <dt>ID:</dt>
     <dd>{{user?.id}}</dd>

     <dt>Email:</dt>
     <dd>{{user?.email}}</dd>
   </dl>
</div>

在这个例子中,我没有错误,但是用户字段都是空的,没有显示任何内容。我试过用这个:

<div *ngIf="user | async; let user; else loading">
<ng-template #loading>Loading User Data...</ng-template>

但它不起作用,控制台显示:

Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' ...

我在另一个组件中执行相同的procress,我使用像IUser []这样的用户数组,这次我用ngfor显示数据,一切都正确,数据按预期显示在浏览器上。我这样做的方式和我上面解释的一样,但是使用ngif或者用户?.id而没有数组。

3 个答案:

答案 0 :(得分:2)

对于最终错误,async管道仅适用于observable。因此,不是将数据保存在用户变量中,然后将其传递给异步管道,而是尝试保存observable本身:const user$ = this._userService.getUser(this.userId),然后将其传递到async管道:{{ user$ | async }}

然后,您可以访问以下属性:{{ (user$ | async).age }}等等。

对于您的初始错误,它可能只是请求的问题。您可以尝试将data的值注销到订阅中的控制台以进行故障排除。也许你需要data.response或其他东西。 (您可以通过使用我上面提到的可观察方法并在模板中执行{{ user$ | async | json }}来查看userService.get的调用对您的影响。

请注意,虽然您可以让手动订阅工作,但您需要自己处理订阅的清理工作。 async管道是这种类型的东西。

有关详细信息,请点击此处:https://angular.io/api/common/AsyncPipe

答案 1 :(得分:2)

API返回用户列表,而不是单个用户(即使您指示响应为IUser)

你需要做一些映射才能获取第一个元素

getUser(id): Observable<IUser>{

      return this.http.get<IUser>(this._url + id).map(resp => resp[0])
                      .catch(this.errorHandler);

    }

请参阅修改后的代码:https://angular-uqsks5.stackblitz.io

答案 2 :(得分:0)

首先,您需要将@ angular / http中的响应导入您的服务。

import { Http, Headers, Response } from "@angular/http";

从rx / js映射:

import { map } from 'rxjs/operators';

然后,在您的服务中,尝试以下操作:

return this.http.get(this._url + id).pipe(
  map((resp:Response) => resp.json())
)

这应该将您的响应映​​射到JSON。订阅observable应该按照你现在在组件中的方式工作。