Невозможно сопоставить ответ HTTP с типом интерфейса в angular 5

Я вызываю HTTP-запрос и привожу полученный ответ к требуемому типу с помощью интерфейса в службе. Ответ HTTP представляет собой объект JSON с некоторой парой элементов «ключ-значение». Я подписался на эту услугу в компоненте. Когда я консольно регистрирую ответ, полученный в функции подписки, он отлично регистрирует объект с парой ключ-значение. Но когда я назначаю этот объект члену класса компонента, кажется, что он не приводится к требуемому типу интерфейса. Потому что, когда я использую ключи переменной члена класса в компоненте html, я получаю сообщение об ошибке: «Невозможно прочитать свойство« X »неопределенного»

Вот фрагменты кода -

Интерфейс

export interface NewsItem {
    status: string;
    totalResults: number;
    articles: any[];
}

Услуга

export class NewsService {
    constructor(private http: HttpClient) {}
    getCategoryNews(): Observable<NewsItem>{
        return this.http.get<NewsItem>(newsUrl);
    }
}

компонент.ts

export class NewsContainerComponent implements OnInit {
newsData: NewsItem;
constructor(private _newsService: NewsService) {}
ngOnInit() {
        this._newsService.getCategoryNews().subscribe(
            (response) => {
                this.newsData = response;
                console.log(this.newsData);
            },
            (err) => {
                console.error(err);
            }
        )
    }
}

компонент.html

<div *ngFor="let item of newsData.articles">
    {{item.description}}
</div>

Фактический ответ на HTTP-запрос выглядит следующим образом.

{
   "status":"ok",
   "totalResults":2,
   "articles":[
      {
         "source":{
            "id":"google-news-au",
            "name":"Google News (Australia)"
         },
         "title":"Former Malaysian PM questioned on graft",
         "description":"Former Malaysian Prime Minister Najib Razak could face criminal charges after being questioned over a corruption scandal."
      },
      {
         "source":{
            "id":"the-guardian-uk",
            "name":"The Guardian (UK)"
         },
         "title":"Manchester Arena attack: thousands to mark anniversary",
         "description":"Series of events across city including a mass singalong are being held one year on from terrorist attack",
      }
   ]
}

В случае с приведенным выше кодом я получаю сообщение об ошибке «Невозможно прочитать статьи о свойствах неопределенного». Почему я получаю эту ошибку даже при вводе HTTP-ответа с интерфейсом?


person Abhinandan Khilari    schedule 22.05.2018    source источник


Ответы (2)


Вы пытаетесь получить доступ к данным до того, как они будут разрешены
В этом случае используйте оператор безопасной навигации ( ?. )
При доступе к свойствам объекта может возникнуть исключение, если объект имеет значение null или неопределенный. Оператор безопасной навигации Angular (?.) — это быстрый и удобный способ защиты от нулевых и неопределенных значений в путях свойств.

<ng-container *ngIf="newsData">
    <div *ngFor="let item of newsData?.articles">
        {{item.description}}
    </div>
<ng-container>
person Vikas    schedule 22.05.2018
comment
Спасибо. Я думаю, что оператор безопасной навигации введен в angular, а в angularjs его не было, верно? Кстати, у angularjs нет проблем при использовании свойств неопределенных объектов в шаблоне, верно? - person Abhinandan Khilari; 22.05.2018

Я думаю, вам нужно использовать оператор безопасной навигации ? для вашего варианта использования, как показано ниже, используемого в коде:

<div *ngFor="let item of newsData?.articles">
    {{item.description}}
</div>

безопасный навигационный оператор ? оператор в Angular, который позволяет избежать любых ошибок, возникающих в случае, если родительское/базовое значение не существует в вашем приложении, а также очень полезно в случае асинхронной привязки

person Pardeep Jain    schedule 22.05.2018
comment
@Pradeep, спасибо. Я думаю, что вы не можете инициализировать поля в интерфейсе, поэтому запись «articles: any[] = []» в интерфейсе невозможна, как я это проверял. Но запись «newsData?.articles» в ngFor устранила ошибку. Но не могли бы вы объяснить об этом? Что именно '?' оператор делает в этом случае? Кроме того, нужно ли мне это для всех полей объекта (newsData), если я использую их в шаблоне? Разве HTTP-ответ не приводится в первую очередь к типу интерфейса? - person Abhinandan Khilari; 22.05.2018
comment
?. может использоваться для поглощения нулевых ссылок в цепочке свойств. Используйте его вместо аксессора точки. в случаях, когда базовое значение может быть нулевым или неопределенным. - person user1608841; 22.05.2018
comment
@AbhinandanKhilari Я не уверен насчет intialize filed in interface, но да, ? называется безопасным оператором навигации в Angular, что позволяет избежать ошибок, возникающих в случае, если родительское/базовое значение не существует в вашем приложении, а также очень полезно в случае асинхронной привязки. - person Pardeep Jain; 23.05.2018
comment
@user1608841 user1608841 да хорошо объяснил !! - person Pardeep Jain; 23.05.2018