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

111 Views Asked by At

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

1

There are 1 best solutions below

5
Chaka15 On BEST ANSWER

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();
 }
}