I'm trying to render an Observable in Angular. I'm making a request to an API to get some data but, when I try render it, nothing appears at the browser.
This is the service I'm using to get the data about 1 user:
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);
}
}
This is the user component:
@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);
}
}
And the view HTML I'm using to render de User is:
<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>
In this example I have no errors but the user fields are all empty, nothing is showed. I've tried to use this:
<div *ngIf="user | async; let user; else loading">
<ng-template #loading>Loading User Data...</ng-template>
But it doesnt works, The console shows:
Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' ...
I'm doing the same procress in another component where I use an array of Users like IUser[], this time I'm showing the data with an ngfor and everything is correct, the data appears at the browser as expected.. I'm doing it the same way I've explained above but using ngif or user?.id and without arrays.
The API returns a list of users, not a single user (even though you indicated the response to be a IUser
)
You need to do some mapping to only take the first element:
getUser(id): Observable<IUser> {
return this.http.get<IUser>(this._url + id).map(resp => resp[0])
.catch(this.errorHandler);
}
See modified code: https://angular-uqsks5.stackblitz.io