Reputation: 65
How can I insert a function call via *ngFor, while this call comes as an inserted String from the Array I'm iterating over?
My array contains a list of user actions that are described by their function names (among others). The template has a part that shall list these actions for each user entry, using Ionic's ion-fab
directive. Instead of writing down each action I want to iterate over the list using *ngFor
and insert each function name into a (click)
attribute.
My current solution doesn't work, though.
Here's my code:
Class
constructor(
public navCtrl: NavController,
public navParams: NavParams,
private usersProv: Users
) {
this.userActions = [
{
'label' : 'Edit',
'function' : 'editUser',
'icon' : 'ios-create-outline',
'color' : 'primary'
},
{
'label' : 'Remove',
'function' : 'removeUser',
'icon' : 'ios-trash-outline',
'color' : 'yellow'
},
{
'label' : 'Send message',
'function' : 'sendMessageToUser',
'icon' : 'ios-send-outline',
'color' : 'secondary'
}
];
console.info('userActions', this.userActions);
}
Template
<ion-fab right>
<button ion-fab mini color="light">
<ion-icon name="ios-arrow-dropleft"></ion-icon>
</button>
<ion-fab-list side="left">
<div *ngFor="let action of userActions">
<button ion-fab mini color="{{action.color}}" title="{{action.label}}" (click)="action.function(user)">
<ion-icon name="{{action.icon}}"></ion-icon>
</button>
</div>
</ion-fab-list>
</ion-fab>
And this is the error I get:
ERROR TypeError: "_v.context.$implicit.function is not a function"
Inserting with curly brackets ((click)="{{action.function}}(user)"
) doesn't help, either. The error then is:
`ERROR Error: "Uncaught (in promise): Error: Template parse errors: Parser Error: Got interpolation ({{}}) where expression was expected at column 0 in [{{action.function}}(user)]`
Is this possible at all?
And is it recommendable to approach it the way I'm doing?
Thanks in advance!
Upvotes: 2
Views: 381
Reputation: 16394
I recommend to use @user184994's solution, bind this
context and use a reference, but if you still wanting to use strings, you can get access to component's methods via this['methodName'](parameter)
, in my example it looks like this[a.function](user)
.
Here is a STACKBLITZ.
Upvotes: 1
Reputation: 18291
Instead of using a string, you should hold a reference to the function, like so
userActions = [
{
'label' : 'Edit',
'function' : this.editUser.bind(this),
'icon' : 'ios-create-outline',
'color' : 'primary'
},
{
'label' : 'Remove',
'function' : this.removeUser.bind(this),
'icon' : 'ios-trash-outline',
'color' : 'yellow'
},
{
'label' : 'Send message',
'function' : this.sendMessageToUser.bind(this),
'icon' : 'ios-send-outline',
'color' : 'secondary'
}
];
Here I'm using bind
, so we don't lose the context of this
when we invoke the function.
Then, in your HTML, you can call it like so:
<button (click)="a.function(user)">{{a.label}}</button>
Upvotes: 4