Как передать два потока субъектов / действий в качестве параметров HTTP в запросе GET для возврата одного объекта / массива объектов в Angular с использованием RxJS?

ЦЕЛЬ: Я хочу ПОЛУЧИТЬ один объект и / или ряд объектов из моей серверной службы, передав пользовательские данные в качестве параметров HTTP с помощью RxJS. Например, я использую декларативный RxJS, поэтому у меня есть два субъекта (поток действий), чтобы получать ввод от пользователя, когда он нажимает «Отправить». Я хочу передать эти значения Subjects, как параметры HTTP, в свой HTTP-запрос, чтобы получить либо указанный объект отсека, либо диапазон отсеков. Первый Subject / UserInput всегда будет обязательным, тогда как второй Subject / UserInput будет необязательным. Итак, если кто-то вводит 4 для первого ввода, а затем ничего для второго ввода. Серверная часть примет оба входа как 4 и «ноль», потому что ничего не было вставлено. В этом случае верните отсек с номером отсека 4. Если есть второй вход, например 6, верните диапазон отсеков от 4 - ›6, если они есть.

Проблема: как передать эти два объекта в качестве параметров http с помощью декларативного RxJS?

Вот два моих объекта и их метод, а также моя попытка выполнить HTTP-запрос в моем bay-service.ts файле.

  private bayStartSelectedSubject = new Subject<number>();
  baySelectedAction$ = this.bayStartSelectedSubject.asObservable();

  private bayEndSelectedSubject = new Subject<number>();
  bayEndSelectedAction$ = this.bayEndSelectedSubject.asObservable();

  selectedBayChanged(selectedBayStartNumber: number, selectedBayEndNumber?: number): void {
    this.bayStartSelectedSubject.next(selectedBayStartNumber);
    this.bayEndSelectedSubject.next(selectedBayEndNumber);
  }

  private HandlingUnitResponseUrlSecondary = 'http://localhost:8080/sbtemplate/readBayInventory';


bayOrBays$ = combineLatest([
    this.baySelectedAction$,
    this.bayEndSelectedAction$
  ])
    .pipe(
      map(([bayStart, bayEnd]) => {
        mergeMap(() => this.http.get<HuResponse>(`${this.HandlingUnitResponseUrlSecondary}/COS/${bayStart}/${bayEnd}`))
      })
    );

Вот где я беру пользовательские данные в моем bay-page.ts файле и вызываю их метод для выдачи значения пользовательского ввода:

onSubmit() {
    this.bayService.selectedBayChanged(this.bayForm.get('bayStart').value, this.bayForm.get('bayEnd').value);
    if(!this.invalidBay) {
      this.bayDoesNotExistError = true;
      this.selectedBay = this.bayForm.get('bayStart').value;
      this.vibration.vibrate(500);
      console.log('Vibrating for 3 second...')
    } else {
      this.navCtrl.navigateForward([`/results/`]);
    }

Я знаю, что код выглядит не очень хорошо, но я не могу найти никакой информации по этому поводу. Спасибо за помощь!

Также Вот серверный API, который я пытаюсь задействовать:

@RequestMapping(value="/readBayInventory/{centerId}/{beginBayId}/{endBayId}", method = GET)
    public ResponseEntity<HUResponse> readBayInventory(@PathVariable String centerId, @PathVariable int beginBayId, @PathVariable(required = false) int endBayId) {

person Donny groezinger    schedule 09.03.2021    source источник
comment
Привет, Донни, спасибо за вопрос. Пожалуйста, не могли бы вы быть более конкретными и задать это в параграфе и фрагменте кода? Помогать намного проще, это много слов, дружище!   -  person jburtondev    schedule 09.03.2021
comment
Вам нужны фотографии моего кода? Я разместил вопрос о другом, и они сказали ввести мой код в StackOverflow. Итак, я получаю неоднозначные результаты, извините. Я не знаю, как еще объяснить это, за исключением того, что у меня есть два объекта, которые принимают пользовательский ввод, независимо от пользовательского ввода, я хочу передать в качестве параметров http в запросе GET для получения одного / диапазона объектов отсека.   -  person Donny groezinger    schedule 09.03.2021
comment
Без проблем, помню, когда я тоже присоединился, временами это немного расстраивало. Просто напишите свой вопрос и код, к которому он относится.   -  person jburtondev    schedule 09.03.2021
comment
Хорошо, надеюсь, я сделал это лучше, а не хуже. Я действительно не знаю, как еще уточнить свой вопрос ...   -  person Donny groezinger    schedule 09.03.2021
comment
с какой проблемой вы столкнулись? Get http не вызывается?   -  person Fan Cheung    schedule 10.03.2021
comment
Текущий код (HTTP-запрос) возвращает Observable ‹void›. Я не знаю, какой оператор или в каком направлении двигаться, чтобы вернуть Observable ‹HuResponse›? Я знаю, что мне нужно сопоставление более высокого порядка, потому что в противном случае оно будет иметь тип Observable ‹Observable ‹HuResponse›› Но я хочу вернуть любой результат в виде массива.   -  person Donny groezinger    schedule 10.03.2021


Ответы (1)


Вы можете попробовать изменить способ объявления bayOrBays и перейти к этой форме

const bayOrBays$ = combineLatest([
  baySelectedAction$,
  bayEndSelectedAction$
]).pipe(
  concatMap(([bayStart, bayEnd]) => this.http.get<HuResponse>(`${this.HandlingUnitResponseUrlSecondary}/COS/${bayStart}/${bayEnd}`))
);

Этот код в основном означает, что каждый раз, когда один из 2 субъектов испускает новое значение, вы запускаете http-вызов и возвращаете его результат. concatMap - это один из так называемых операторов более высокого уровня, то есть оператор, который принимает функцию, которая возвращает Observable, и возвращает значение, испускаемое таким Observable (другими словами, он выравнивает внутренний Observable, возвращаемый функцией, переданной в качестве входных).

Другими операторами более высокого уровня являются mergeMap (также известные как flatMap), switchMap и exahustMap. У всех есть несколько разное поведение, но для HTTP-вызовов обычно безопасным значением по умолчанию является concatMap. Вы можете получить представление о том, как использовать rxJ в общих случаях использования, связанных с http, из эта статья.

Наконец, причина, по которой в настоящее время вы получаете Observable<void> как тип bayOrBays$, частично связана с тем фактом, что функция, которую вы передаете mergeMap, ничего не возвращает. Помните, что если вы используете фигурные скобки для определения тела функции, вы должны явно использовать оператор return, чтобы что-то вернуть. Напротив, если вы используете однострочный формат для тела (то есть без фигурных скобок), функция возвращает то, что является результатом выполнения этой одной строки.

Итак, этот формат (который вы использовали) ничего не возвращает

const myFunction = () => {
  doStuff();
}

в то время как оба этих формата возвращают все, что возвращает doStuff()

const myFunction = () => {
  return doStuff();
}

const myFunction = () => doStuff()
person Picci    schedule 10.03.2021
comment
Да, это то, к чему я стремился. Правильно ли мой подход, получая вводимые пользователем данные и передавая их, как я, в свой HTTP-запрос? Благодарю за ваш ответ! Я начинаю лучше разбираться в RxJS, и мне это очень нравится. У меня все еще есть накладные расходы, которые заставляют меня немного осмыслить! Спасибо! - person Donny groezinger; 10.03.2021