Угловая производственная ошибка: свойство не существует для типа «объект» - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть приложение Angular 7, которое извлекает данные из двух отдельных конечных точек:

  1. http://localhost:1337/sms
  2. http://localhost:1337/total

Я могууспешно сделать запрос GET к этим конечным точкам в разработке.Тем не менее, я получаю следующую ошибку при запуске ng build --prod:

ERROR in src/app/app.component.html(20,29): : Property 'total' does not exist on type 'object'.

В качестве теста я временно удалил {{ total.total }} из app.component.html, снова запустил ng build --prodи это сработало.

Разве это не правильный способ делать запросы GET к двум отдельным конечным точкам или я делаю что-то еще неправильно, возможно, в моем файле сервера Node?

app.component.ts

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

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

export class AppComponent implements OnInit {
  signees: object;
  total: object;

  constructor(private http: HttpClient){}

  ngOnInit(): void {
    this.http.get('http://localhost:1337/sms').subscribe(
      data => {
      this.signees = data;
      }
    );

    this.http.get('http://localhost:1337/total').subscribe(
      data => {
      this.total = data;
      }
    );

  }
}

Соответствующий app.component.html код

<section class="page-section mx-auto">
    <h3 class="text-center">{{ total.total }} people have signed the petition</h3>
    <div class="container">
      <div class="row">

      <div class="col-sm-6 col-lg-3"
      *ngFor="let signee of signees; index as i">
        <div class="card">
          <div class="card-body">
            <p class="h2">{{ signee.name }}</p>
            <ul class="signee-meta text-muted">
              <li>#{{ i + 1 }}</li>
              <li>{{ signee.date }}</li>
            </ul>
          </div>
        </div>
      </div>

    </div><!-- row -->
    </div><!-- container -->

  </section>

/total конечная точка (MongoDB)

app.get('/total', (req, res) => {
    collection.countDocuments({}, function(err, num) {
      assert.equal(null, err);
      res.send({total: num});
    });
  });

EDIT (добавлена ​​структура данных)

Структура данных (MongoDB)

{ 
  "_id" : ObjectId("5c61e0b658261f10280b5b17"), 
  "name" : "Bill Kickok", 
  "number" : "+14950395584", 
  "date" : "2/11/19" 
}

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Эта ошибка возникает при запуске ng build --prod, потому что этот процесс сборки за кадром работает с компиляцией Ahead Of Time.

Вот что происходит с AOT на основе угловой документации .

Раннее обнаружение ошибок шаблона

Компилятор AOT обнаруживает и сообщает об ошибках привязки шаблона на этапе сборки, прежде чем пользователи смогут их увидеть.

Вы получаетеэта ошибка, потому что вы пытаетесь отобразить свойство всего объекта, в то время как вы объявили total как object.

Чтобы избавиться от этой ошибки, вы должны либо создать interface для этой переменной.Например,

export interface Total {
   total: number
   // any other properties total might include
}

. Затем используйте этот интерфейс для определения типа в вашем компоненте следующим образом:

total: Total

Если вы не хотите создавать интерфейс - , который являетсяплохая практика - вы можете определить итоговое значение как any (total: any).

Наконец, непосредственное выполнение запросов http в вашем компоненте также является плохой практикой .Вы должны создать службу, затем добавить те methods, которые отвечают за связь с вашим бэкэндом, затем добавить эту службу в ваш компонент и вызвать этот метод.

Я бы посоветовал вам взглянуть на угловая документация .

0 голосов
/ 19 февраля 2019

вам нужно запустить ваш объект внутри конструктора.

пример:

  constructor(private http: HttpClient){
    total = new Total();
}

Итого - ваш класс.Это рекомендуется в angular.io.Запустите VAR внутри конструктора.

0 голосов
/ 19 февраля 2019

Если возможно, было бы неплохо строго указать эти свойства, поэтому вместо:

  signees: object;
  total: object;

If будет:

  signees: Signee[];
  total: Total;

Где Signee и Total будут интерфейсами:

export interface Signee {
  id: number;
  name: string;
  date: string;
  // ...
}

export interface Total{
  id: number;
  total: number;
  // ...
}

ПРИМЕЧАНИЕ. Вышеприведенное будет соответствовать структуре JSON, возвращенной в data (поэтому кто-то спросил, как выглядит структура вашего data).

И если total - это всего лишь одно число, которое вы получаете назад, то это будет просто:

total: number;

И вы просто привязываете к total, а не total.total.

Затем можно использовать эту строгую типизацию при отправке запроса, чтобы убедиться, что ответ имеет правильную форму:

this.http.get<Signee[]>('http://localhost:1337/sms').subscribe(
  data => {
  this.signees = data;
  }
);

Обратите внимание на общий параметр, указанный в приведенном выше коде.

...