Search code examples
angulartypescriptobservableprimengp-dropdown

How to solve this anti-pattern: calling method in template


I am using a p-dropdown from PrimeNG and i have to display the updated values.

At the moment in my HTML in the p-dropdown i typed this:

[options]="getReportTypes()"

In my typescript I have this situation:

reports: ReportTemplateGroupList | undefined;
@Input() set reportGroup(reportGroup: ReportTemplateGroupList | undefined | null) {
  if (reportGroup) {
    this.reports = reportGroup;
  }
  this.setReportTypeAndSubset();
}


getReportTypes(): ReportType[] {
  const reportTypes: ReportType[] = [];
  this.reports?.forEach((report) => {
    if (report.name) {
      reportTypes.push({ label: report.name });
    }
  });
  return reportTypes;
}

This is an anti-pattern since i'm calling a method in the template. I'm trying to find a way to update the values in another manner: for example with an Observable but I'm not able to do it since everything is still really new to me. Do you have any idea how to implement it?

I can't just simply store the value in a variable because I need that constantly updated value so it should be something that is permanently "called" in my template

Thanks for your help


Solution

  • Why don't you simply store the returned value of getReportTypes() method to a property (eg. reportTypes) and pass that property inside HTML to the child component. That's the way to prevent calling getReportTypes() in template every time change detection runs.

    public reportTypes: ReportType[] = [];
    
    getReportTypes(): ReportType[] {
    this.reports?.forEach((report) => {
      if (report.name) {
        this.reportTypes.push({ label: report.name });
      }
    });
    

    In the template just simply: [options]="reportTypes"

    Example with ngOnChanges():

    ngOnChanges(changes: SimpleChanges) {
     if (changes.reportGroup) {
      this.getReportTypes();
     }
    }