Я хочу создать службу для заполнения раскрывающегося списка из базы данных. Я пробовал это:
Класс торговца:
export class Merchant {
constructor(
public id: string,
public name: string,
public state_raw: string,
public users: string,
) {}
}
Торговая служба:
getList(): Observable<Merchant> {
return this.http.get<Merchant>(environment.api.urls.merchants.base, {});
}
SQL-запрос:
@Override
public Iterable<Merchants> findAll() {
String hql = "select e from " + Merchants.class.getName() + " e";
TypedQuery<Merchants> query = entityManager.createQuery(hql, Merchants.class);
List<Merchants> merchants = query.getResultList();
return merchants;
}
Рабочий пример:
@GetMapping("/list")
public Iterable<Merchants> getMerchantsList() {
return merchantRepository
.findAll();
}
Я пробовал это:
@GetMapping("/list")
public ResponseEntity<?> getMerchantsList() {
return StreamSupport.stream(merchantRepository.findAll().spliterator(), false)
.map(mapper::toDTO)
.map(ResponseEntity::ok)
.findFirst()
.orElseGet(() -> notFound().build());
}
Я хочу использовать картограф, прежде чем отправлять ответ. В настоящее время список в Angular пуст. Наверное, мне стоит вернуть Iterable<Merchants>, а не ResponseEntity<MerchantDTO>?
Я использую Java 10.
Да, как я могу это реализовать?
Ну, изменив тип на Array <Merchant>. Кроме того, почему ваш метод getMerchantsList () возвращает void вместо ... списка продавцов? Почему он использует findFirst ()? Вы хотите вернуть всех торговцев, а не только первого. Вам нужно собрать (Collectors.toList ()), а не findFirst (). OrElseGet (). И вы хотите вернуть этот список, а не игнорировать его.
Виноват. Извините. Пост обновлен.




Есть несколько проблем с обеих сторон. Начнем со стороны сервера. Вы хотите вернуть список продавцов, чтобы заполнить раскрывающийся список список, поэтому вы правильно назвали свой метод getMerchantsСписок (). Но вместо того, чтобы возвращать список, как указывает его имя, он возвращает void. void ничего, нада, отсюда и пустой ответ.
Поэтому вам нужно вернуть List<Merchant> или, если вы действительно хотите (но здесь это не нужно, поскольку вы не хотите устанавливать ничего, кроме тела ответа), ResponseEntity<List<Merchant>>. Вызов findFirst() контрпродуктивен. Вам не нужен первый продавец в списке. Вам нужен весь список:
@GetMapping("/list")
public List<MerchantDTO> getMerchantsList() {
return StreamSupport.stream(merchantRepository.findAll().spliterator(), false)
.map(mapper::toDTO)
.collect(Collectors.toList());
}
или
@GetMapping("/list")
public ResponseEntity<List<MerchantDTO>> getMerchantsList() {
List<MerchantDTO> list = StreamSupport.stream(merchantRepository.findAll().spliterator(), false)
.map(mapper::toDTO)
.collect(Collectors.toList());
return ResponseEntity.ok(list);
}
Обратите внимание, что код был бы проще, если бы ваш метод findAll () возвращал List вместо Iterable. Вы можете просто использовать findAll().stream() для получения потока.
На стороне клиента вы делаете ту же ошибку. Вы хотите, чтобы тело ответа было множество продавцов, чтобы заполнить раскрывающийся список список. Но вы используете Observable<Merchant>. Вам нужен Observable<Array<Merchant>>. А передача пустого объекта параметров в get() бесполезна:
getList(): Observable<Array<Merchant>> {
return this.http.get<Array<Merchant>>(environment.api.urls.merchants.base);
}
Наконец, вы обманываете себя, создавая класс. HttpClient никогда не создаст экземпляр вашего класса. Он не знает об этом и просто анализирует JSON, который он получает, на простые старые объекты JavaScript. Поэтому вам действительно следует определять интерфейс, а не класс:
export interface Merchant {
id: string;
name: string;
state_raw: string;
users: string;
}
Вам также действительно следует использовать Spring-data-jpa. Это значительно упростило бы ваши репозитории.
Ваша остальная услуга вернет список торговцев. Ваш сервис angular возвращает Observable, излучающий одного продавца. Это не совпадает. Вам нужен массив для заполнения dropdon, не так ли?