0

I have been stumped on this for about 2 hours now.

My problem is that I need to load an array from a MySQL database using PHP and Ajax, and use the array in JavaScript.

I got that part working fine however the part where it references "onClick" and contains a function to run does not work. It provides numerous errors which say the exact same thing.

Uncaught RangeError: Maximum call stack size exceeded at buttons.<computed>.onClick (app.js:1281)

The example of the array is the following:

[
    {
        "text": "Lost to Competitor",
        "onClick": "closeOpportunity(\"Lost to Competitor\", el, stages)"
    },
    {
        "text": "No Budget \/ Lost Funding",
        "onClick": "closeOpportunity(\"No Budget \/ Lost Funding\", el, stages)"
    },
    {
        "text": "No Decision \/ Non-responsive",
        "onClick": "closeOpportunity(\"No Decision \/ Non-responsive\", el, stages)"
    },
    {
        "text": "Price",
        "onClick": "closeOpportunity(\"Price\", el, stages)"
    },
    {
        "text": "Other",
        "onClick": "closeOpportunity(\"Other\", el, stages)"
    },
    {
        "text": "Won via Another Opportunity",
        "onClick": "closeOpportunity(\"Won via Another Opportunity\", el, stages)"
    }
]

My code for loading the array is the following:

function closeOpportunity(name, el, stages) {
    $$("#opportunity_loss_reason2").text(name);
    $$("#closedType").text("Closed Lost");
    $$("#convertToProject").hide();
    $$("#lostReasonLI").show();
    upStepper(el, stages);
}

var stages = [
    "enquiry",
    "qualification",
    "proposal",
    "negotiation",
    "closed"
];

var buttons = [];

app.request.json('scripts/lostButtonsArray.php', function (data) {
    buttons = data;
    console.log(buttons);
});

buttons.forEach((v, i) => {
    console.log(v['onClick']);
    buttons[i]['onClick'] = function() { window.eval.call(window, v['onClick'])(el, stages); };
});

app.dialog.create({
    title: 'ECOM',
    text: 'Why was the opportunity lost?',
    cssClass: 'custom-dialog',
    closeByBackdropClick: 'true',
    buttons: buttons,
    verticalButtons: true,
}).open();

I have already tried using regular eval() and loading the code directly without any sort of helper (eval, window.eval).

I will be happy to provide more information to help solve this problem if I haven't provided enough information.

  • 1
    Why are you using `window.eval.call()` instead of just `eval(v.onClick)`? – Barmar Jan 20 '20 at 23:16
  • @Barmar, hey! I tried using eval(v['onClick']) originally however it did not work so I had a look around at other questions and found this so I tried it. https://stackoverflow.com/questions/13906161/javascript-pass-eval-variables – Joseph Shenton Jan 20 '20 at 23:18
  • I also need to pass the variables `el` and `stages` to the onClick function. – Joseph Shenton Jan 20 '20 at 23:18
  • Does `closeOpportunity()` return a function? You're trying to call the result of eval with `(el, stages)`. – Barmar Jan 20 '20 at 23:18
  • I have to run now, but the `onClick` properties need to evaluate to a function, not call the function directly. – Barmar Jan 20 '20 at 23:19
  • I have updated my question to include the closeOpportunity code, but no it doesn't return a function. It is the function I am trying to execute. – Joseph Shenton Jan 20 '20 at 23:20

1 Answers1

0

Found the solution.

I was trying to load "name" instead of "text"

Working function

app.request.json('scripts/lostButtonsArray.php', function (data) {
        buttons = data;
        buttons.forEach((v, i) => {
            buttons[i]['onClick'] = function() { eval('closeOpportunity')(v['text'], el, stages); };
        });
    });
  • I note this for your benefit: People worse than me will exploit your use of `eval()`. Not a great solution. – spork Jan 21 '20 at 00:46
  • What's the point of using `eval()` with a fixed string? Just write `closeOpportunity(v.text, el, stages)` – Barmar Jan 21 '20 at 00:51