1
votes

I'm having trouble with accumulating Observables in RxSwift. To clarify, I have an array of artists. For each artist, I am calling a function that returns the tracks of the artist, in the form of "Observable<[NewTrack]>". In the end, I want to have an observable of accumulated Newtracks, "Observable<[NewTrack]>".

More generally, how do I emulate appending items to an array with Observables? My solution to this was the code below in which I created a behaviorRelay to monitor the state of the array and kept updating it each iteration. But the end result I got wasn't what I expected: the returned Observable<[NewTrack]> only contained the tracks of the last artist in the array. I think my problem may have something to do with the fact that I want to also concatenate the 2 arrays within both observables.

let observable = BehaviorRelay<Observable<[NewTrack]>>(value: Observable<[NewTrack]>.empty())
for artist in artists {
    let newTracks = self.sessionService.getNewTracksForArtist(artist: artist)
    let currentTracks = observable.value
    observable.accept(Observable.concat(currentTracks, newTracks))
}
return observable.value
1

1 Answers

1
votes

Ok after I drew the process out, I realized that the concatenation result I was getting was "[[Artist1Tracks], [Artist2Tracks]]". What I wanted was "[Artist1Tracks+Artist2Tracks]". Thankfully, there is a perfect operator for doing this: scan. It's like reduce but emits each intermediate value as well. All I did was add to the concatenation line:

observable.accept(Observable.concat(currentTracks, newTracks).scan([], accumulator: +))

Effectively, this concatenated all instances of arrays within the array.