Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular 5: setting (click) value from an object not working

I have a nav menu that is rendered using a navigation.ts json file for the menu items. When it gets to the navitem component it uses a ngIf to check if the item from the navigation file has a "function" key and if it does, the desired behavior is for it to use the string value from item.function in the object to fill the value for the (click) event.

In reality, the console throws an error saying "_co.item.function is not a function"

HTML

<span class="nav-link" *ngIf="item.function" (click)="item.function()" matRipple>
    <mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
    <span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
    <span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
        [ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
    {{item.badge.title}}
    </span>
</span>

Navigation.ts

      [{
"id": "accounting",
"title": "Accounting",
"type": "collapse",
"children": [
  {
    "id" : "salesmenSalesLocation",
    "title": "Salesmen Sales Location",
    "type": "item",
    "function": "handleSelect(ReportTypes.SalesmenSalesLocations)"
  },
  {
    "id": "laggingLedgerEntries",
    "title": "Lagging Ledger Entries",
    "type": "item",
    "function": "handleSelect(ReportTypes.LaggingLedgerEntries)"
  }
 ]}]

I have also tried it as (click)="item.function" with no success.

like image 412
CouchCode Avatar asked Feb 13 '26 10:02

CouchCode


2 Answers

I'm assuming you can change the data source here, because otherwise I don't see any good solution.

A string is not a function, and while you can turn it into one with eval that is a bad idea. What you should really do instead is just pass in a value that tells the function what to use.

Change your data to something like this:

{
  "id" : "salesmenSalesLocation",
  "title": "Salesmen Sales Location",
  "type": "item",
  "reportTypeSource": "SalesmenSalesLocations"
},
{
  "id": "laggingLedgerEntries",
  "title": "Lagging Ledger Entries",
  "type": "item",
  "reportTypeSource": "LaggingLedgerEntries"
}

Then pass that value to your function and use that to tell it where to look:

handleSelect (reportTypeSource: string) {
    const reportType = ReportTypes[reportTypeSource]
    // continue as before
}

And call it in your HTML like this:

(click)="handleSelect(item.reportTypeSource)"
like image 121
John Montgomery Avatar answered Feb 14 '26 23:02

John Montgomery


Problem lies here:

"function": "handleSelect(ReportTypes.LaggingLedgerEntries)"

And here:

(click)="item.function()"

You cannot simply pass a string and expect the component to execute a function and also know exactly what to do. Here you need to pass the actual function.

Your setup looks over-config'd. I would tear the config down and put the logic into the component itself. Don't be afraid to have more template as well, if anything it makes things more legible (as opposed to the config)

like image 32
mchl18 Avatar answered Feb 14 '26 22:02

mchl18