combineLatestfunction. It does what it says – takes latest value from each Observable it’s given and combine them together.
combineLatestproduces new value every time once of its arguments produces a value. Then all values combine into an array and passed to next Observable.
oftakes one argument and returns Observable that will produce this argument as its value. It makes it easier for us to combine existing photos wih new ones. If we deal with Observables everywhere we can combine them really straightforward.
newPhotos$changes every time user uploads some photo, we have to accumulate all uploads into one array. We’ll do it in
allNewPhotos$Observable, with operator
scantakes every value you give it and accumulates them into one aggregate value.
scanthink: huge, huge snowball. Everytime you add little snowball to it, it gets bigger, but it’s the same, huge snowball. So
scantakes many little snowballs as inputs and produces huge one as output. Our particular
scan, instead of snow, takes lots of photos uploaded over time, and concatenates them into one, huge list of uploaded photos. There’s also
startWithto make sure that our
allNewPhotos$Observable has starting value before
photos$Observable how to exactly combine those two. It goes like this:
combineLatestproduces new array with existing and uploaded photos, let’s take these two arrays, put them into one and flatten. That way we’re getting one array with all photos. If you’d like to make this code a bit shorter, you could do something like:
photosfield to Observable
photos$. (By know you may have noticed that we’re using
$at the end of each variable that is Observable. It’s just a convention, you dont’ have to follow it, but most programmers who write RxJS will understand it.) Because we’ve changed data source we have to change
activePhoto$Observable. Before it filtered photos straight from static property:
photos$Observable as data source.
withLatestFrom. It’s a close cousin of
combineLatest, it’s being used to combine few Observables. The difference is that in our
activePhoto$only one Observable controls flow of data and it is:
activePhotoID$. It means that
activePhoto$produces new value only when
activePhotoID$produces new value. No matter how many times
photos$will have new value, we’re waiting for
activePhotoID$and once it produces a value we’re taking last seen value from
photos$and sending it downstream. This way, we can access
photos$every time we need it, but active photo will actually change only when
activePhotoID$changes. (You may also hear that
photos$. It means every time we get new value from
activePhotoID$we also get a sample from
asyncpipe twice in our template. What
asyncpipe does is: it creates Subscription and displays data in HTML. Subscription is an object that listens to Observable changes. So in the template we have one data source
activePhoto$, but two listeners:
… | async. It’s a mess. We want to have one Subscription for one data source. Otherwise data in our Component is desynchronized.
ActivePhotoComponentand create one Subscription there. This Subscription will feed data to our template, so template will always get proper data.
photo. Now, we can forget about
asyncin our template, since from template point of view,
photoproperty is now static.
ngOnDestroyfor that. Access
photoSubscriptionand tell it, that it should stop listening for any changes. Your work here is done
photoSubscription, you may now rest peacefully.