угловой, как получить массив вложенных объектов из двух таблиц, один ко многим связанных

#angular #typescript #rxjs #observable #switchmap

Вопрос:

Привет всем, у меня есть 2 таблицы mysql: itemsClass, которая содержит список возможных классов, и ItemType, который ссылается на ItemClass и содержит значения типов определенного класса.

Я пытаюсь создать сервис, который возвращает наблюдаемый<Элемент[]><Элемент []>, объединяющий два http.get наблюдаемых, соответствующих этому интерфейсу:

 interface Item{
 itemcClassId:any; //itemClass.id, from itemClass select
 itemClassName:any; //itemClass.name from itemClass select
 itemTypeValue?:any;    //from itemType select, if itemType contains only a value of the first table's class
 itemTypeValues?:any[]; //if itemType's values are multiple
}
 

Я наткнулся (после бесконечных поисков) на такую структуру кода, как эта

 getEmploye(name: string): Observable<any> {
    return this.getClass(name).pipe(
      switchMap((response) => {
        return forkJoin(of(response),this.getType(class.id);),
               map(res=>{
                 return {...res[0],values:...res[1]}
               })
      })
    ) 
  }
 

но это вернет один элемент, в то время как мне нужен массив элементов..
есть какие-нибудь намеки?

спасибо всем

РЕДАКТИРОВАТЬ: код, который я вставил, не был настроен, просто вставлен, потому что он, казалось, соответствовал аналогичным потребностям (или, по крайней мере, части).;

Настроенная версия (возвращающая только один элемент) будет состоять (насколько я могу понять) примерно в следующем:

 getItem(id: number): Observable<Item> {
    return this.http.get(url_to_ItemClass_rest_api).pipe(
      switchMap((item) => {
        return forkJoin(of(item),
this.http.get(url_to_ItemType_rest_api_filtered_by_foreign_key_item.id/);),
               map(res=>{
                 return {...res[0],values:...res[1]}
               })
      })
    ) 
  }
 

Комментарии:

1. Откуда это class исходит class.id ? Интерфейс показывает itemcClassId (возможно, опечатка, я предполагаю, что это так itemClassId ), но код использует только class.id и не class.itemClassId ?

2. просто не хотел использовать точку в имени свойств структуры.. просто отредактировано, чтобы уточнить

3. Возможно, вы не совсем поняли вопрос. Вы используете букву а class.id в коде. Но я нигде не вижу, class чтобы переменная/объект были определены.

4. что this.getClass возвращается? Список itemsClass или один конкретный itemsClass ? И непонятно, что this.getType возвращается. Также я бы посоветовал правильно писать типы — это поможет вам понять, как следует изменять ваши данные

5. отредактировано еще раз, теперь надежда яснее

Ответ №1:

forkjoin устарел в этом режиме. Вы должны передать массив::

 forkjoin([of(item),
this.http.get(url_to_ItemType_rest_api_filtered_by_foreign_key_item.id/)])
 

Если вам нужно одно возвращение с ключом и значением, вы можете вернуть что-то вроде следующего: const ret = { …res[0], значения: res[1] };

   getEmploye(id: number): Observable<any> {
    return this.getClass(id).pipe(
      switchMap(item => {
        return forkJoin([of(item), this.getType(item.id)]).pipe(
          map(res => {
            const ret = { ...res[0], values: res[1] };
            return ret;
          })
        );
      })
    );
  }
 

Для массива попробуйте что-то вроде этого:

getClass(имя: число): Наблюдаемый<Массив<{идентификатор: строка}><{идентификатор: строка}>>

GetType(classId: строка): Наблюдаемый<Массив< строка >< строка >>

 getEmploye(id: number): Observable<any> {
    return this.getClass(id).pipe(
      switchMap(items => {
        const forkRequest: Array<any> = [of(items)];
        items.forEach( item => forkRequest.push(this.getType(item.id)));

        return forkJoin(forkRequest).pipe(
          map((res: Array<any>) => {
            const returnList: Array<{id: string, values: Array<any>}> = [];
            res.forEach((item: any, index: number) => {
              if (index > 0) {
                const returnObj = { id: res[0][index - 1].id, values: item };
                returnList.push(returnObj);
              }
            });
            return returnList;
          })
        );
      })
    );
  }
 

Комментарии:

1. это звучит.. спасибо вам.. кстати, мне понадобится массив элементов, поэтому правильным прототипом функции будет GetItems(): Observable<Item[]> {}

2. поэтому get(url_to_ItemClass_rest_api) должен возвращать список идентификаторов, и для каждого идентификатора будет сделан вызов get(url_to_ItemType_rest_api_filtered_by_foreign_key_item.id/)?

3. ДА.. все это с чем-то вроде указателя внутри карты переключения или чего-то подобного … вот чего я не могу понять..

4. Отредактированный. Дай мне знать, если ты этого хотел

5. это блестяще.. Я впишу это в свой код и попробую … где ты прятался с этими навыками из stackoverflow????