0

I have this ngAfterViewInit lifecycle hook:

ngAfterViewInit() {
    this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);

    this.subscription = this.dataService.dataChanged
      .subscribe(
        () => {
          this.getData();
        }
      );

    this.getData();
  }

I want the subscription to run before the this.getData() that's outside the subscription, and only if that didn't happen, I would like for the this.getData() that's outside the subscription to run.

How can I make that happen? Putting it in ngOnInit doesn't work because this is a paginated table and that only works after the page has been rendered. I need to have the subscription for when the user adds new data to the table and I want it to be visible automatically.

Edited If I run the code like it is written above, then when first navigating to the page, my data is correctly loaded to my paginated table from the server. Then, the user can add a new data item, using a form that's in another component. When the user is done adding the new item, they are navigated back to this table. The way it looks now, the table is first loaded without the new addition, and is then reloaded with the new addition. What I wanted to happen is for the first loading to not be visible to the user - so that when they are navigated back, they see the correct data right away.

  • when you use subscribe, the execution is asynchrone so you cannot predict if it will be executed before or after code outside the subscription. Why you don't just delete the last row ? the row this.getData into the subscription will be executed each time your dataChanged observable will emit a value – Gauthier T. Aug 16 '20 at 17:39
  • @GauthierT., the problem is that if I delete that last row, the getData() method is never called, because the subscription is only emitted after the user manually adds data to my data source. Any thoughts? – tired_but_inspired Aug 17 '20 at 05:19
  • you can hide this component, that way it will be created and subscription will be available. – Raam Mishra Aug 24 '23 at 15:29

1 Answers1

1

You need to change the flow of your code as subscriptions are asynchronous.

 private callGetData: boolean

 ngAfterViewInit() {

    this.callGetData = true;

    this.sort.sortChange.subscribe(() => {
       this.paginator.pageIndex = 0;
       if(this.callGetData) this.getData();
       this.callGetData = false;
    })

    this.subscription = this.dataService.dataChanged
      .subscribe(
        () => {
          this.getData();
        }
      );
  }

This way you will call getData() only after ngAfterViewInit() executes not every time subscription receives event.

or you can remove the flag if you want getData() inside subscription too.

Hope it works!

Ajeet Eppakayala
  • 1,186
  • 1
  • 10
  • 17
  • first of all, thank you. The problem now is that the subscription for dataChanged isn't always emitted, so when I first navigate to this page, the data from the server just doesn't arrive. It is only emitted after I add a new data item. Any ideas? – tired_but_inspired Aug 17 '20 at 05:18
  • Is `sortChange()` getting emitted? And could you pls, edit the question and explain more on what is needed? – Ajeet Eppakayala Aug 17 '20 at 05:51
  • ```sortChange()``` is not getting emitted until the data is loaded. The data is only loaded if the ```this.getData()``` method is run, but this way it never gets to run. I'm going to edit my question now, so that it contains a better explanation. – tired_but_inspired Aug 17 '20 at 06:24
  • I edited my question - hope it gives a better understanding as to what I want. – tired_but_inspired Aug 17 '20 at 06:30
  • when new record is added, you can simply add that to table rows of your table(after add record finishes). if its update, you can take the `id` and replace the row with new data. – Ajeet Eppakayala Aug 17 '20 at 08:12
  • Thank you. Unfortunately, I still couldn't make the subscription be called no matter what I did. – tired_but_inspired Aug 18 '20 at 05:50