Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 229 Vote(s) - 3.54 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Hot and cold AngularFire observables

#1
I have the following code in a component in my Angular2/Firebase app:

ngOnInit() {
this.allItems = this.angularFireDatabase.object(`projects/${id}/results`).map(
results => {
const x = itemMapper(results);
console.log(x); // <-- executes three times
return x;
});

const groupedData = this.allItems.map(groupMapper);
this.towers = groupedData.map(towerMapper);
this.units = groupedData.map(unitMapper);
}

I am using `this.allItems`, `this.towers` and `this.units` in the template with the `async` pipe:

<sanddance [items]="allItems | async">

<p-dataTable [value]="towers | async">
<p-dataTable [value]="units | async">

The code runs fine, but **the problem is that the log executes three times**--in other words, the mapping to create `this.allitems` is running three times. If I remove the `this.towers` and `this.units` assignments, then the log executes only once as expected. In other words, the `this.towers = groupedData.map(towerMapper); ` line seems to be causing an extra call to the mapper creating `this.allItems`, although it shouldn't need to and I don't want to it. Could it even be re-accessing the data from the Firebase database, which would obviously be a problem, especially since this is a lot of data?

Based on my limited understanding on "hot" and "cold" observables, it seems that the AngularFire observable is being treated as "hot", and re-triggered when someone downstream tries to map it (or subscribe to it, which is essentially what the `async` pipe does).

What am I missing?


Reply

#2
<!-- language-all: lang-ts -->

The AngularFire2 observables are cold observables. Each subscription will see a separate Firebase [`Reference`](

[To see links please register here]

) created internally - to which listeners are then attached, etc.

When the composed observables in your snippet are subscribed to, each will effect a subscription to the AngularFire2 `object` observable. If you want a single subscription to be used instead, you can use the [`share`
](

[To see links please register here]

) operator:

import 'rxjs/add/operator/share';

this.allItems = this.angularFireDatabase.object(`projects/${id}/results`).map(
results => {
const x = itemMapper(results);
console.log(x); // <-- this should execute only once
return x;
}).share();

const groupedData = this.allItems.map(groupMapper);
this.towers = groupedData.map(towerMapper);
this.units = groupedData.map(unitMapper);

The `share` operator:

> Returns a new Observable that multicasts (shares) the original Observable. As long as there is at least one Subscriber this Observable will be subscribed and emitting data. When all subscribers have unsubscribed it will unsubscribe from the source Observable. Because the Observable is multicasting it makes the stream hot. This is an alias for `.publish().refCount().`
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through