Наблюдаемая находка вложенного свойства - PullRequest
0 голосов
/ 26 мая 2018

Observable возвращает этот объект

[
  {
    "args": { },
    "output": [
      {
        "id": "1",
        "name": "Jack",
        "lastName": "Sparrow",
      },
      {
        "id": "2",
        "name": "Davy ",
        "lastName": "Jones",
      }
    ],
  }
]

Есть ли способ использовать операторы RxJx для возврата элемента массива output, где id===2?Таким образом, чтобы получить только это:

{
  "id": "2",
  "name": "Davy ",
  "lastName": "Jones",
}

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

Мой текущий код (я знаю, чтоfind часть неверна):

  public getUserData(id: number) {
    this.http.get<any>(URL)
      .pipe(
         find(element => element.output)
      )
      .subscribe(res => {
       console.log(res)
     })
  }

Ответы [ 4 ]

0 голосов
/ 26 мая 2018

Если вас не интересует излучение из наблюдаемых (например, как часто они излучаются), вы можете просто использовать filter из собственного Javascript Array Prototype , а не filter из наблюдаемых.По сути, они разные, но если у вас нет веских причин использовать Observable, вы можете просто использовать массив один.Код намного короче и более производительный:

public getUserData(id: number) {
    this.http.get<any>(URL)
        .map(data => data.output.filter(x => x.id === '2'))
}

На самом деле, если вы SURE фильтруете по id, который считается уникальным, выможно использовать .find () с использованием синтаксиса es6.Он вернет вам первый элемент выполненного условия:

public getUserData(id: number) {
    this.http.get<any>(URL)
        .map(data => data.output.find(x => x.id === '2'))
}
0 голосов
/ 26 мая 2018

Просто используйте комбинацию mergeMap (часто называемую flatMap в других Rx реализациях) и filter!

mergeMap позволяет вам:

  1. map каждый из ваших элементов в списках (то есть, выводить список значений для каждого события)
  2. flatten списки вместе возвращаются в один поток событий

... который вы затем filter, чтобы сохранить только те, которые соответствуют предикату по вашему выбору (в вашемcase: output => output.id === 2).


Вы можете поиграть с фрагментом кода ниже, где вы можете отредактировать полученный ответ и нажать соответствующую кнопку, чтобы вызвать событие.

const data = [{
  "args": {},
  "output": [{
      "id": "1",
      "name": "Jack",
      "lastName": "Sparrow",
    },
    {
      "id": "2",
      "name": "Davy ",
      "lastName": "Jones",
    }
  ],
}];

const textarea = document.querySelector('#data-source');
const button = document.querySelector('#trigger-response');

// Assume `myObservable comes from the result of an Ajax request`
const myObservable = rxjs
  .fromEvent(button, 'click')
  .pipe(rxjs.operators.map(() => JSON.parse(textarea.value.replace(/,(?=\s*\})/mg, ''))));

myObservable.pipe(
  rxjs.operators.mergeMap(response => response[0].output),
  rxjs.operators.filter(output => output.id === '2')
).subscribe(x => console.log(x));
body {
  display: flex;
  align-items: center;
}

textarea {
  flex-grow: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.2.0/rxjs.umd.min.js"></script>
<textarea id="data-source" rows="20">[
  {
    "args": { },
    "output": [
      {
        "id": "1",
        "name": "Jack",
        "lastName": "Sparrow",
      },
      {
        "id": "2",
        "name": "Davy ",
        "lastName": "Jones",
      }
    ],
  }
]</textarea>
<button id="trigger-response">Click Me</button>
0 голосов
/ 26 мая 2018

Я бы пошел так:

this.http.get<any>(URL)
    .pipe(
        mergeAll(), // flatten the root array
        mergeMap(item => item.output), // flatten the output array
        filter(output => output.id === '2')
    )
    .subscribe(res => {
        console.log(res); // Tahdah!!
    })
0 голосов
/ 26 мая 2018

Вы можете использовать фильтр:

public getUserData(id: number) {
  this.http.get<any>(URL)
  .pipe(
     filter(element => {
       for (let output of element.output){
           return output.id === "2";
       }
     })
  )
  .subscribe(res => {
   console.log(res)
  })
}
...