jimmyrap
jimmyrap

Reputation: 99

onNext method doesn't fire on observable

I have a method that returns an observable and calls another method to process the received data. If in my onNext method I call this.addNewData() only it works like a charm.

data: BaseData[] = [];


initData() {
 this.dataProvider.getData()
.subscribe(this.addNewData());
}

However, if I want to do something more with the data received and use lambda, my method this.addNewData() is being called but as a result my data collection remains empty.

initData() {
 this.dataProvider.getData()
.subscribe(
          data => {
            this.addNewData();
            this.showProgressSpinner = false;
            console.log(this.data);
          });
    }
}

  private addNewData() {
    const dataIds = this.data.map(i => i.dataId);
    return fetchedData => fetchedData
      .filter(i => ! dataIds.includes(i.dataId))
      .forEach(i => this.data.push(i));
  }

I'm new to Angular and I would like to understand why it happens.

Upvotes: 0

Views: 151

Answers (1)

user2216584
user2216584

Reputation: 5602

As you know that subscribe() takes optional three callbacks next, error, complete.

The first callback is next which requires to have a function which takes an input [this input would be the value emitted by the observable] and returns void.

Now let's understand what your addNewData() function returns -

private addNewData() {
    const dataIds = this.data.map(i => i.dataId);
    return fetchedData => fetchedData
      .filter(i => ! dataIds.includes(i.dataId))
      .forEach(i => this.data.push(i));
  }

It is returning an arrow function which takes an input and returns void.

Now come back to your first way to subscribe -

initData() {
 this.dataProvider.getData()
.subscribe(this.addNewData());
}

Above subscribe is filling this.data because this.addNewData() returns a function (i.e. arrow function) as expected by the next callback of subscribe() and the returned function of this.addNewData() gets executed which is your following arrow function -

fetchedData => fetchedData
      .filter(i => ! dataIds.includes(i.dataId))
      .forEach(i => this.data.push(i));

Now hope you got why first subscribe is filling this.data

Now come to the second way of subscribing:

initData() {
 this.dataProvider.getData()
.subscribe(
          data => {
            this.addNewData();
            this.showProgressSpinner = false;
            console.log(this.data);
          });
    }
}

In above subscribe you are already passing a function (i.e. an arrow function) so this function will be executed. Now you are not doing anything with the return function of this.addNewData() and that function is having the responsibility to update your collection this.data. You should do the following to make it work:

initData() {
     this.dataProvider.getData()
    .subscribe(
              data => {
                const retFunc = this.addNewData();
                retFunc(data);
                this.showProgressSpinner = false;
                console.log(this.data);
              });
        }
    }

Hope this answers your question.

Upvotes: 1

Related Questions