An application has some buttons on a screen that should execute different functions when clicked. It goes like a little like this:
<template>
<ul>
<li v-for="MenuItem in MenuItems">
<button type="button" @click.prevent="handleClick({Function: MenuItem.Function.Name, Params: MenuItem.Function.Params })">
{{ MenuItem.Label }}
</button>
</li>
</ul>
</template>
<script setup>
const MenuItems = [
{
Label: `Edit`,
Function: {
Name: `editItem`,
Params: {
ItemID: 1
}
},
{
Label: `Delete`,
Function: {
Name: `deleteItem`,
Params: {
ItemID: 1
}
}
]
function handleClick({Function, Params}) {
Function.apply(Params) // throws not a function error
eval(Function+"()") // throws not a fuction error
}
function editItem(){
console.log(`edit item`);
}
function deleteItem(){
console.log(`about to delete item`);
}
</script>
All I want to do is run whatever has been passed to the Function
argument in handleClick()
and also include the Params
argument as an argument to the Function
that needs to be executed e.g. editItem(1)
or deleteItem(1)
;
Trying apply()
and eval()
don’t seem to work and throws an error that Uncaught TypeError: Function.apply is not a function
. I am using VueJS as the framework, but this is really a Javascript question.
3
Answers
Make the functions as methods of an object and call the methods:
Playground
I reviewed your code.
Please try with this codebase.
Thanks
The
Function
property in yourMenuItems
array is not a reference to an actual function. It’s a string (editItem
,deleteItem
), and you cannot call or apply a string like a function.To fix the problem, you can pass actual function references instead of strings in the MenuItems array. Here’s the corrected code: