Визуализировать в Angular 5
Я пытаюсь сделать Observable в Angular. Я делаю запрос к API, чтобы получить некоторые данные, но, когда я пытаюсь сделать это, в браузере ничего не появляется.
Это сервис, который я использую для получения данных об одном пользователе:
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);
}
}
И HTML-код представления, который я использую для визуализации de User:
<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' ...
Я делаю то же самое в другом компоненте, где я использую массив Users, такой как IUser[], на этот раз я показываю данные с помощью ngfor, и все правильно, данные отображаются в браузере, как и ожидалось. I ' Я делаю это так же, как я объяснил выше, но использую ngif или user?.id и без массивов.
3 ответа
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/
Что касается последней ошибки, то async
труба работает только с наблюдаемыми. Поэтому вместо сохранения данных в пользовательской переменной и последующей передачи их в асинхронный канал попробуйте сохранить саму наблюдаемую переменную: 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
Во-первых, вам нужно будет импортировать Response из @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. Подписка на наблюдаемое должно работать так, как вы сейчас это делаете в своем компоненте.