2017-01-18 2 views
3

У меня есть настройка, где я запрашиваю firebase для списка любимых сообщений пользователя.RxJS - switchMap не испускает значение, если входной наблюдаемый пустой массив

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

Проблема возникает, когда пользователю не нравится единственный левый пост. В этом случае (когда подобный массив становится пустым) ничто не срабатывает из наблюдаемого, и представление не обновляется (всегда есть хотя бы одно сообщение).

С одной стороны, это поведение кажется логичным и понятным, но, с другой стороны, я не уверен, как сделать окончательный Исследуемый излучение, даже если вход в switchMap пуст. Может быть, должен сменить оператора.

getUserFavourites(userId = ""):Observable<Post[]> 
{ 
    if (!this.userFavourites$) { 
    this.userFavourites$ = this.af.database.list('/ranks_by_user/' + userId, { 
     query: { 
      limitToFirst: 50 
     } 
     }) //Emits value here (even empty array) 
     .switchMap((likes: any[]) => Observable.combineLatest(
     likes.map(like => this.af.database.object("/posts/" + like.$key).first()) 
    )) //Does not emit new value here if likes array was empty 
     .map(p => { 
     return p.map(cit => Post.unpack(p)); 
     }).publishReplay(1).refCount() 
    } 
    return this.userFavourites$; 
} 
+0

Я думаю, что когда массив любит это нуль должен бросить ошибку, и что он останавливает цепь, вы можете попытаться добавить уловку –

+0

Спасибо за идею, приятель. Это, вероятно, будет работать. На самом деле, я дам ему попробовать :) –

+0

Нашел отличное решение. Проверьте это. –

ответ

1

Решил проблему путем добавления условия внутри switchMap:

Оригинал - https://github.com/ReactiveX/rxjs/issues/1910

getUserFavourites(userId = ""):Observable<Post[]> 
{ 
    if (!this.userFavourites$) { 
    this.userFavourites$ = this.af.database.list('/ranks_by_user/' + userId, { 
     query: { 
      limitToFirst: 50 
     } 
     }) //Emits value here (even empty array) 
     .switchMap((likes: any[]) => { 
     return likes.length === 0 ? 
     Observable.of(likes) : 
     Observable.combineLatest(
      likes.map(like => this.af.database.object("/citations/" + like.$key)) 
    ) 
    }) //Emits either combined observables array or empty array 
     .map(p => { 
     return p.map(cit => Post.unpack(p)); 
     }).publishReplay(1).refCount() 
    } 
    return this.userFavourites$; 
} 
+0

это была спасательная жизнь для меня! –

0
.switchMap((likes) => likes.length > 0 ? 
    Observable.combineLatest(
    likes.map(like => this.af.database.object("/posts/" + like.$key).first(): 
    Observable.empty() // if emit empty() then .map() will not run 
) 
.map(...) 
+2

Не могли бы вы добавить немного больше объяснений вокруг своего ответа? – Colwin

+0

Для сети siwtchMap(). Map(). Если вы возвращаете пустой Observable (Observable.empty()) внутри switchMap, то цепочка .map() не будет запущена. –

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