2016-12-01 3 views
2

У меня есть следующий код, который возвращает наблюдаемый с деталями элементов для каждого ключа элемента:Возвращает массив/объект вместо наблюдаемой с помощью карты RXJS

this.list = this.af.database.list("API_URL") 
     .map((ItemKeys) => { 
     return ItemKeys.map((ItemKey) => { 
      return this.af.database.object(API_URL + "/" + ItemKey); //I need this as the object (not observable) 
     }); 
     }).subscribe((items) => { 
     this.lineData = items; //A list of observables 
     }); 

Кода itereates по каждому ключу элемента и получает данные позиции с другой конечной точки. Проблема в том, что он извлекает наблюдаемые данные каждого элемента, и мне это нужно в объекте (наблюдаемый результат).

Я попытался вернуть результат подписки с помощью следующего кода, но все мои данные изделий являются пустыми (не определены):

this.list = this.af.database.list("API_URL") 
     .map((ItemKeys) => { 
     return orderItemKeys.map((ItemKey) => { 
      this.af.database.object("API_URL" + "/ItemKey.$key) // So I tried to subscribe to this.. 
      .subscribe((data) => { 
      return data; 
      }); 
     }); 
     }).subscribe((items) => { 
     this.lineData = items; // A list with undefined items 
     }); 

Как я могу вернуть объект данных элемента как объект, а не наблюдаемые объекта в моем случае?

ответ

0

Вы должны заменить map на flatMap, так как он способен сгладить Observable<Observable<T>>.

var responseStream = requestStream 
    .flatMap(function(requestUrl) { 
     return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl)); 
}); 

responseStream.subscribe(() => {}); 

Пытаясь адаптироваться и упростить код этого

const databaseList =() => Rx.Observable.from(['a6b54x4', '1e23sa4q']); 
const databaseObject = (id) => Rx.Observable.of({ id, status: 'ok' }) 

databaseList() 
    .flatMap(x => databaseObject(`id/${x}`)) 
    .reduce((x, y) => x.concat(y), []) 
    .subscribe(console.log); 

В принципе, это все еще сглаживает Observable<Observable<T>>, а затем с помощью сокращения, сливает все в массив результатов.

https://jsfiddle.net/6pLpo3cp/

+0

Извините, этот ответ не имеет понятия, как я могу использовать 'flatMap' в моем случае, где и как. Я попытался изменить свой первый '.map' на' .flatMap', но он этого не сделал. – TheUnreal

+0

@ TheUnreal, извините, мой плохой. Тогда не было слишком задумчиво. Посмотрите сейчас, если это поможет или нет. –

0

Не возвращайте подписку (от подписки) внутри оператора. Вероятно, это не так, как вы хотите.

Для внутренней части, где вы извлекаете список объектов, вы должны иметь возможность поворачивать массив наблюдаемых, созданных с Array#map(), в наблюдаемый более высокий порядок с Observable#from(). Вам нужно mergeAll(), чтобы взять эту серию наблюдаемых обратно в один поток, а затем собрать все испущенные элементы в массив с toArray(). Затем вы извлекаете последний наблюдаемый с mergeMap().

this.list = this.af.database.list("API_URL") 
    .mergeMap((ItemKeys) => { 
    return Observable.from(ItemKeys.map((ItemKey) => { 
     return this.af.database.object(API_URL + "/" + ItemKey); 
    })).mergeAll().toArray(); 
    }) 
    .subscribe((items) => { 
    this.lineData = items; 
    }); 
+0

Я думаю, что 'lineData' по-прежнему будет возвращать массив наблюдаемых при возврате наблюдаемого:' return this.af.database.object (API_URL + "/" + ItemKey); '. Мне нужно вернуть результат каждого наблюдаемого. Во всяком случае, я просто проверил ваш код и 'this.lineData' пуст и не достиг (я ставлю консольный журнал в подписке и ничего не показываю) – TheUnreal

+0

Убрал метод' toArray() 'и возвращает мои наблюдаемые значения не как array (в то время как в моем коде он извлекает их как массив, но мне они нужны не наблюдаемые.) – TheUnreal

+0

@ TheUnreal обновил ответ, потому что toArray должен быть внутри внутреннего mergeMap, потому что list() никогда не завершается. –

Смежные вопросы