Сопоставить наблюдаемый вложенный объект с другим объектом - PullRequest
0 голосов
/ 02 октября 2018

Я пытаюсь отобразить ответ от вызова API, скажем, на объект Product.Кажется, я не могу найти способ сделать это правильно.

Ответ имеет следующую структуру:

{
  "data": [
    {
      "id": 1,
      "name": "keyboard",
      "details": {
        "parent": 1,
        "price": 50,
        "other": "info"
      }
    },
    {
      "id": 2,
      "name": "mouse",
      "details": {
        "parent": 2,
        "other": "info",
        "price": 20
      }
    }
  ],
  "total-records": 2,
  "more": "something"
}

Порядок деталей ответа не может быть гарантирован.(Обратите внимание на цену в деталях). Я пытаюсь сопоставить объект выше с одним новым объектом, который содержит только следующие свойства:

{
    "id": 1,
    "name": "keyboard",
    "price": 50
},
{
    "id": 2,
    "name": "mouse",
    "price": 20
}

Я использую угловые и Observables для получения данных.Теперь я получаю значение, сопоставляю его и могу либо получить детали, либо свойства объекта 1-го уровня, такие как data.id или data.name.Однако получение таких деталей, как цена, немного сбивает меня с толку.

Я много исследовал карты слияний, плоских карт, даже lodash и бесчисленные часы, пытаясь выяснить это, но я не могу найти правильный путьсделать это.

Можно ли использовать фильтр в комбинации карт для достижения этой цели?Любая информация высоко ценится.

Вот мой код:

ngOnInit() {
    //Get by criteria
    this.productService
      .get(url, httpOptions)
      .pipe(
        map((items: Response<Product>) => {
          this.details = items["details"].filter(
            // Filter possible null values
            details=> details!==null;
          );
          this.header = items
        }),
        tap(() => console.log(this.header))
      )
      .subscribe();
  }
  
  // Header is level 1 info like name and id
  // Detail is level 2 info like price.
  // I have to have a filter on the details because sometimes 

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Это странный способ работы с "глобальным" назначением внутри оператора RxJS.Эти вар должны быть добавлены из подписки.И способ сбора данных также странный.

Вы никогда не захватываете атрибут «данные» из ответа, и вы рассматриваете «детали» как массив, но в вашем ответе это простой объект.

После того, что ваш API восстанавливает, 1 объект с как минимум 3 атрибутами данные список продуктов, всего записей , больше ...,

Что вы могли бы сделать:

this.productService
  .get(url, httpOptions).pipe(
      map((res) => res.data), // extract data attribut
      map((data) => {
        return data.map((aProd) => {   //map the product and take only id, name, price
          return {
            id: aProd.id,
            name: aProd.name,
            price: aProd.details && aProd.details.price
          };
        });
      })).subscribe((productList) => {
        console.log(productList);
      });
0 голосов
/ 02 октября 2018

Это не зависит от RxJS, но от простого старого Javascript.

Чтобы сопоставить объект с ожидаемым, попробуйте следующее:

this.productService
  .get(url, httpOptions)
  .pipe(
    map((items: Response<Product>) => items
      .map(item => ({ id: item.id, name: item.name, price: item.details && item.details.price || '?' }))),
    tap(mappedItems => console.log(mappedItems))
  )
  .subscribe(mappedItems => this.header = mappedItems);

Я также позволил себе немного переместить код, чтобы сделать его более понятным (например, делаячто-то в подписке, а не непосредственно на карте).

Этот код выполняет сопоставление Observable, заставляя его возвращать новый набор данных.

Новый возвращенный набор данных также является отображением, но отображением ваших фактических данных, а не наблюдаемых.

Теперь с сопоставленными данными вы можете применить их к своим заголовкам, что делается при подписке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...