Визуализировать в 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. Подписка на наблюдаемое должно работать так, как вы сейчас это делаете в своем компоненте.

Другие вопросы по тегам