Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJS - subscribe only once but do not complete Observable

imagine situation when you have some Observable that contains data that changes in real time, example below...

interface User {
   name: string;
   projectId: string;
   dataThatChangesALotInRealTime: Object;
}

userData: Observable<User>

This userData observable is used in component to show some data that changes in real time. e.g.

<p>
{{ (userData | async)?.dataThatChangesALotInRealTime }}
</p>

Now I want to insert some data to database according to current data in userData observable. Here is the function

addToDatabase() {
  let sub = this.userData.subscribe(data => {
     this.exampleDatabase.doc(`test/${data.dataThatChangesALotInRealTime.id}`)
          .add({ test: 'hello'})
     sub.unsubscribe() // <- This
  })
}

Question

Is this a correct solution to unsubscribe inside subscription to avoid multiple insertion into database? Is there a different/better way to do this?

This is just minimalistic example, if you have some questions or my explanation is poor, let me know in comments and I will update my question. Thank you

like image 585
Raold Avatar asked Dec 09 '18 12:12

Raold


People also ask

Can you subscribe to an Observable multiple times?

It turns out that as the Observable is just a definition, let's remember that in a sense its something close to a function declaration, if we subscribe to it multiple times this means that each time a new HTTP request will be issued, one for each subscription.

What happens if you don't unsubscribe from an Observable?

As you probably know when you subscribe to an observable or event in JavaScript, you usually need to unsubscribe at a certain point to release memory in the system. Otherwise, you will have a memory leak. A memory leak occurs when a section of memory that is no longer being…

Do I need to unsubscribe from a completed Observable RxJS?

complete() after it has emitted all of it's values. There's no need to unsubscribe. It completes on it's own, which means it unsubscribes all subscribers automatically. This is also the reason why you don't often notice any memory leaks.

Do you have to subscribe to an Observable?

Sadly, no. There are at least two cases where you should explicitly subscribe to Observables in components and directives. First is when the Observable makes a change to the outside world. Most commonly, this is done by issuing a POST (or DELETE or PUT) through HTTP, meant to update the backend.


1 Answers

You can use the first operator:

this.userData.pipe(first()).subscribe(...);

This will automatically complete (and therefore unsubscribe) after the first value has been emitted.

Note that you should ensure that it emits at least once before completing as otherwise an error will be thrown. If you can't ensure this, you can use take(1) instead:

this.userData.pipe(take(1)).subscribe(...);

Note that this doesn't actually modify the userData observable directly, so other subscriptions to it will continue emitting regardless. This is because operators in rxjs do not modify observables but instead return a new observable.

like image 110
Ingo Bürk Avatar answered Nov 15 '22 14:11

Ingo Bürk