0

I am restructuring an angular project where I found below functionality.

In app.component.ts file

ngOnInit() {
this.portfolioID = Number(sessionStorage.getItem('portfolioID'));
console.log(this.portfolioID);
this.sharedService.getPortfilioID().subscribe(portfolioID => {
  if (portfolioID && portfolioID !== 0) {
    this.items.forEach(item => {
      if (item.displayText === 'Business Licenses' && item.items.length > 0) {
        item.items.forEach(childItem => {
          childItem.url = childItem.defaultUrl;
        });
      }
    });
  }
});
}

They are getting some Id from localstorage which was set by clicking on a link in another component.

Another.component.html

<ng-template kendoGridCellTemplate let-dataItem *ngIf="column.isActionable && titleName == 'Customer Search'">
    <a href="javascript:void(0)" *ngIf="column.attributeName == 'portfolioName'"
      (click)="viewPortfolioDetails(dataItem.portfolioID)">{{dataItem.portfolioName}}</a>
  </ng-template>

Another.component.ts

viewPortfolioDetails(portfolioID: number) {
sessionStorage.setItem('portfolioID', portfolioID.toString());
this.sharedService.setPortfolioID(portfolioID);
}

So, as it was set on click, initially when page loads first time before click, I am not able to get the ID and the subsequent functionality is not working. So, my question is can I call the onInit() method of the app.component again? Or is there any better approach to do this. Thanks.

vamsi
  • 1,488
  • 3
  • 28
  • 66

2 Answers2

0

Please use the following link Javascript - telling setInterval to only fire x amount of times?

Here You can write contents of your oninit() using setintervalX()

This way you can call contents of oninit multiple times

Shlok Nangia
  • 2,355
  • 3
  • 16
  • 24
0

You don't have to call the ngOnInit() twice. The variable childItem.url will be set in app component as long the portfolioIDs are pushed correctly to the observable in the shared service. You could try the following in the service

Shared service

import { Subject } from 'rxjs';

@Injectable()
export class SharedService {
  private portfolioIdSource = new Subject<number>();
  private portfolioId$ = this.portfolioIdSource.asObservable();

  public setPortfolioID(portfolioID: number) {
    this.portfolioIdSource.next(portfolioID);
  }

  public getPortfilioID(): Observable<number> {
    return this.portfolioId$;
  }
}

And also make sure the value obtained from session storage is used at the beginning of the app life-cycle.

App component

subscription: any;

ngOnInit() {
  const portfolioID = sessionStorage.getItem('portfolioID');    // <-- will be called only once at the beginning of app life-cycle
  if (portfolioID !== null && Number(portfolioID) !== 0) {
    this.setUrl();
  }

  this.subscription = this.sharedService.getPortfilioID().subscribe(    // <-- will be triggered everytime new portfolioID is pushed
    portfolioID => {
      if (portfolioID && portfolioID !== 0) {           // <-- will not be called at app beginning because no value in observable 
        this.setUrl();
      }
    }
  );
}

setUrl() {
  this.items.forEach(item => {
    if (item.displayText === 'Business Licenses' && item.items.length > 0) {
      item.items.forEach(childItem => {
        childItem.url = childItem.defaultUrl;
      });
    }
  });
}

ngOnDestroy() {
  if (this.subscription) {
    this.subscription.unsubscribe();
  }
}
ruth
  • 29,535
  • 4
  • 30
  • 57
  • in setUrl() method, items is not accessible right? forEach is not working with this approach. – vamsi Apr 09 '20 at 12:17
  • In the code you've shown in the question, `this.items` is a member variable and it should be available everywhere in the component. – ruth Apr 09 '20 at 12:40