Не удается получить раскрывающийся список для привязки к массиву, возвращаемому моей службой

У меня есть служба, которая содержит метод, который получает список сотрудников:

export class EmployeeService {

    private employeesUrl = 'http://localhost:portnum/api/employees';


    getEmployees(): Observable<IEmployee[]> {
        return this.http.get<IEmployee[]>(this.employeesUrl).catch(this.errorHandler);
    }
}

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

employees = [];

constructor(private fb: FormBuilder, private _employeeService: EmployeeService) {
    this.transactionForm = fb.group ({
      'employee': [null, Validators.required]
    });
  }

  ngOnInit() {
    this._employeeService.getEmployees().subscribe(data => this.employees = data, error => this.errorMsg = error);
  }

и в моем html-коде у меня есть выпадающий список, который привязывается к списку сотрудников:

<span style = "padding-right:60px;">{{'Employee' | translate}}*
          <select [ngModel] = "null" formControlName = "employee" [ngClass] = "displayErrors ? 'inputRedBorder': 'input'" required >
            <option value = "null" disabled selected>{{'SelectEmployee' | translate}}</option>
            <option *ngFor = "let employee of employees">{{employee}}</option>
        </select>
        <p class = "error-msg" *ngIf = "displayErrors" name = "errorMsg">
            {{'RequiredField' | translate}}</p>
    </span>

Однако вместо раскрывающегося списка всех возвращенных сотрудников я получаю следующую ошибку:

ERROR Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed
    at DefaultIterableDiffer.webpackJsonp../node_modules/@angular/core/esm5/core.js.DefaultIterableDiffer.diff (core.js:7495)
    at NgForOf.webpackJsonp../node_modules/@angular/common/esm5/common.js.NgForOf.ngDoCheck (common.js:2583)
    at checkAndUpdateDirectiveInline (core.js:12368)
    at checkAndUpdateNodeInline (core.js:13889)
    at checkAndUpdateNode (core.js:13832)
    at debugCheckAndUpdateNode (core.js:14725)
    at debugCheckDirectivesFn (core.js:14666)
    at Object.eval [as updateDirectives] (TransactionPortalComponent.html:23)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:14651)
    at checkAndUpdateView (core.js:13798)

Объект представляет собой массив, поэтому я не уверен, почему он говорит, что разрешены только массивы и итерации. Что я делаю не так?

Обновлено:

Ответ от api должен выглядеть так:

{
    _employeeList :
    [{
        _employeeKey : ""employee1""
    },
    {
        _employeeKey : ""employee2""
    }],
   _errorDetails :
   {
        _message : ""successful"",
       _status : 200
   }
}

Но я только возвращаю массив [].

Может быть, это связано с моим интерфейсом? :

export interface IEmployee {
    employee: string;
}

Не могли бы вы сделать console.info(JSON.stringify(this.employees)) после подписки на сервис и опубликовать результат здесь?

edkeveked 19.03.2018 20:08

@edkeveked Я получаю [] в качестве вывода в консоли. Просто пустой массив. Значит, это может быть проблема с данными API? Как лучше всего справиться с пустыми массивами?

Euridice01 19.03.2018 20:19

Возможно, вы можете использовать директиву *ngIf перед запуском цикла. Рассмотрим мой ответ ниже

edkeveked 19.03.2018 20:24
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
1
3
32
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В конструкторе вы внедрили службу как _employeeService, но в методе ngOnInit () вы вызываете this._transactionService.getEmployees (). Это должно быть this._employeeService.getEmployees ().

извините, не проблема. Мне пришлось переименовать некоторые вещи для этого сообщения SO. Я исправил опечатку, но проблема не исчезла.

Euridice01 19.03.2018 20:05

Мне кажется, что ваши данные возвращаются как объекты, отсюда и ошибка [Object Object]. Ваша HTML-привязка ищет employee.someProp, но вы не привязываетесь к свойству объекта. Вы утешили свои данные в методе ngOnInit, чтобы убедиться, что они возвращаются правильно?

Austin 19.03.2018 20:11

Когда я выводил на консоль, он превратился в пустой массив []

Euridice01 19.03.2018 20:19

В теге span вы можете указать * ngIf = "employee", если хотите поймать пустой массив и не показывать раскрывающийся список. Затем вы можете добавить дополнительный div или что-то в этом роде с помощью * ngIf = "! Employee", если вы хотите показать что-то вроде «Сотрудники не найдены!». Похоже, у вас может быть ошибка api, если вы возвращаете пустой массив.

Austin 19.03.2018 20:26
Ответ принят как подходящий

Я думаю, что то, как вы выполняете цикл, неверно, поскольку вы хотите иметь тег <option> для каждого сотрудника.

Кроме того, поскольку ваш массив может быть пустым, вы можете сначала проверить, содержит ли массив данные или нет. Возможно, вы можете рассмотреть возможность использования <ng-template> и ng-container.

Получив этот ответ от вашего api, вы должны внести следующие изменения:

услуга

API возвращает JSON, а не массив

getEmployees(): Observable<any> {
        return this.http.get<any>(this.employeesUrl).catch(this.errorHandler);
    }

составная часть

Получить массив

ngOnInit() {
    this._employeeService.getEmployees().subscribe(data => this.employees = data._employeeList, error => this.errorMsg = error);
  }

шаблон

Поскольку вы хотите отображать не сам объект, а его значение, вы можете сделать следующее:

 <ng-container *ngIf = "employees?.length>0">
  <ng-template ngFor let-employee [ngForOf] = "employees">
   <option>{{employee._employeeKey}}</option>
  </ng-template>
 </div>

создать форму INTO функция подписки

Eliseo 19.03.2018 20:39

Я должен получить ответ в следующем формате: pastebin.com/F3jrYFpS Мне интересно, связано ли это с тем, как я настроил свой интерфейс? Я отредактирую свой пост

Euridice01 19.03.2018 20:40

Большое спасибо. Это была проблема с форматом объекта json, и вы правы, для шаблона мне нужно добавить _employeeKey для привязки к правильному полю. Большое спасибо за твою помощь! Но стоит ли в будущем создавать интерфейс, соответствующий json, и делать его строго типизированным?

Euridice01 19.03.2018 21:17

Я пришел из фона javaScript, поэтому, честно говоря, даже если мне нравится набирать TypeScript, я не люблю сильно ограничивать себя этим. Так что, я бы сказал, это вопрос предпочтений. Вы должны поступать так, как считаете нужным :)

edkeveked 19.03.2018 21:19

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