3
votes

I have been trying to understand what is happening with this code.

I understand combineLatest emits a value, emit the last emitted value from each observable. and Object.assign copies all enumerable own properties from one or more source objects to a target object.

I understand this far, but what I don't get, is how they are used together (combineLatest and Object.assign) in that context.

combineLatest(_route.pathFromRoot.map(route => route.params), Object.assign)

This is a reference https://github.com/angular/material.angular.io/blob/master/src/app/pages/component-category-list/component-category-list.ts#L28

2

2 Answers

1
votes

Object.assign is used as projection function see this example.

_route.pathFromRoot.map(route => route.params) will return an Array of Observable.

combineLatest will take latest value of each Observable of the Array and then pass them in the projection function, leading to an object with all params as properties.

1
votes

combineLatest used to have an optional resultSelector parameter where you could map the results to whatever you wanted to. So they are using Object.assign as a resultSelector. This parameter has now been deprecated and you should use map() instead. https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/combineLatest.ts#L17

So they are using this syntax to merge all emissions into a single object (I think that's pretty clever way of using Object.assign by the way :)).

Equivalent code without the resultSelector parameter should be like this I think:

combineLatest(_route.pathFromRoot.map(route => route.params))
  .pipe(
    map(Object.assign.apply),
  )

The resultSelector function received results as separate arguments (res1, res2, res3) while combineLatest propagates them further in a single array ([res1, res2, res3]) so that's why I can't just use map(Object.assign).