#Behaviour Subject subscribing twice or more without next();

32 messages · Page 1 of 1 (latest)

jovial yacht
#

When I console.log my subscribe from my Behaviour Subject, it returns more than one console.log and I cannot understand why because I am doing only one next() call. I do have others method calling next() along the application, but I am not listening to them. I am using http requests with Behaviour Subject and sometimes when it happens my application is doing two or more http requests when should be done just one.

my code:

  onGetDocs = () => {
    // My console.log() is showing up twice or more... Whyyy? right below my console is my GET function making it be called also twice or more.
    this.documents_filters_dialog.docsFilters.subscribe(docsFilters => {
      console.log('docsFilters: ', docsFilters)
  }
gray pendant
#

Try to add a console.log i suspect you are subscribing twice. Maybe you have the component twice or you call onGetDocstwice ```ts
onGetDocs = () => {
console.log('!!!!!!! I will subscribe !!!!!!!!!!')
this.documents_filters_dialog.docsFilters.subscribe(docsFilters => console.log('docsFilters: ', docsFilters));
}

weak hazel
#

It's a behavior subject

#

So when you subscribe you get the current value

#

When you next you get a second value

jovial yacht
jovial yacht
weak hazel
#

Well you don't need a second next

#
const sub = new BehaviorSubject('hello');
sub.subscribe(x => console.log(x)); // log "hello" because it's the "current" value
sub.next('world'); // will log "world"
jovial yacht
#

That's actually what I am doing. I am using my behaviourSubject in some not-related components to send my data with next(), just like you did, to update my current value. I need to have only one subscribe since my next() is called, wherever it is, but I am getting two or more

#

I've just tried to use take(1) to take the first subscribe from my behaviour subject, but once I did this I couldn't send more next's();

    this.documents_filters_dialog.docsFilters.pipe(take(1)).subscribe(docsFilters => {
      console.log('docsFilters: ', docsFilters)
}

#

look, it's returning two console.log() inside my subscribe, which for me is not making any sense because I had have just updated my currentValue once.

#

It's much worse when it happens with my GET requests because I just need to do only one request, but because of this I'm doing two, three or more

pearl apex
#

use an observable instead of a behavior subject

#

behaviour subjects emit the current value on subscription while observables only get new values from when they were subscribed

#

you could also not subscribe in your component and use an async pipe

viscid remnant
#

This is very hard to help you because the issue can be completly different than what you are actually thinking.
The code snippet you gave is not very helpful. How many time are you calling GetDocs?
How you behaviourSubject looks like?
Where is located your function ? inside a component or a service ? how many times is your component rendered?
It would be way easier if you show a more detailed snippet?

gray pendant
#

as Raziel said, you should get one log as soon as you subscribe. You say that you get two ore more logs.
when do you get them? look at the precise timestamp, this could give us a hit about what's going on.

also please share the code where you call next()

jovial yacht
#

Here's my behaviour subject:

  docsFilters = new BehaviorSubject<DocsFilters>({sevenDays: true, older: false, text: '', amountPerPage: 10});
#

As I mentioned before, I call my next() in some functions along my application, here's where:

  onChangeOlderDocs = (event: MatCheckboxChange) => {
    this.olderDocs = event.checked;
    this.documents_filters_dialog.docsFilters.next({older: this.olderDocs, sevenDays: false, text: this.filterDocsListTxt});
  }
  onSearchDocsLastDocs = (inputValue: string) => {
    this.global_variables.currentPage = 1;
    this.documents_filters_dialog.docsFilters.next({sevenDays: !inputValue ? true : false, older: this.olderDocs, amountPerPage: 10, text: inputValue});
  }
  handleSetDocsFilters = () => {
    this.documents_filters_dialog_service.docsFilters.next({older: this.showOlderDocs, sevenDays: false, text: ''});
    
    this.handleCloseDocumentsFiltersDialog();
  }
#

Every time some filter changes and I need to update my documents table data, I am using my Behaviour Subject to get the currentValue, which are my doc filters, and then I am calling my GET request based on my Behaviour Subject's response, though it is returning me two or more responses causing two or more requests

#

I did send only and ONLY one next() (I believe so, because I am not calling any other function at the right moment) and my Behaviour Subject subscribed twice. Whyyy

#

thank you for your time, guys. I really appreciate!

gray pendant
#

add a console.log() before each .next() in order to be sure that they are NEVER called

jovial yacht
#

I did this and my console.log showed up exactly how many times I called the function. I called three times each .next() and my console showed three times.

gray pendant
#

if you call next 3 times then you should see docsFilters: four times. right?

jovial yacht
#

Look at this. I called my .next() on onChangeOlderDocs once, only once I called the function, but I got two subscribes

#

this is the function I called only once:

  onChangeOlderDocs = (event: MatCheckboxChange) => {
    console.log('onChangeOlderDocs');
    
    this.olderDocs = event.checked;
    this.documents_filters_dialog.docsFilters.next({older: this.olderDocs, sevenDays: false, text: this.filterDocsListTxt});
  }
#

and here's my subscribe:

  onGetDocs = () => {

// Here I am doing my subscribe; It consoles twice
    this.documents_filters_dialog.docsFilters.subscribe(docsFilters => {

      console.log('docsFilters: ' + docsFilters)

...
    })
  }
gray pendant
#

that's because behaviourSubject always emits a value once you subscribe, and then it emits a second value when you call next()

you could use ReplySubject(1) instead or use .pipe(skip(1)) to skip the first emission

jovial yacht
#

I can't use replaySubject because I do need an initial value. I tried to use skip(1), but then my subscribe is not even happening

viscid remnant
#

and did you put a console.log inside your getDoc function (where the subscribe is called)