简体   繁体   中英

Javascript passes function and receives error: Uncaught TypeError, process is not a function

This code runs fine. My IDE (RubyMine) sees no problem with it. But Chrome DevTools throws an error both in the Source and in the Console. Is there some way to clean this up?

Uncaught TypeError: process is not a function

$(document).ready(function () {
    let buttonWatch = function (process) {
        $(this).off('click');
        alert(typeof(process)); // This alerts "function"
        process();              // The error is thrown here
        return $(this).on('click', buttonWatch);
    };
    $("#loginButton").on('click', function () {
        function process() {
            alert("Running a process.");
        }
        buttonWatch(process);
    });
});

Revised code as recommended shows same issues:

let myProcess;
let process;
$(document).ready(function () {

    let buttonWatch = function (process) {
        $(this).off('click');
        alert(typeof(process));  // alerts "function"
        process();               // Error thrown here
        return $(this).on('click', buttonWatch);
    };

    $("#loginButton").on('click', function () {
        function myProcess() {
            alert("Running a process.");
        }
        buttonWatch(myProcess);
    });

});

You are getting error when you add on click event on button dynamically within event process itself. So you are trying to take off click event, do some processing and then add the event back. But problem is when you add event handler back to your button click, you are not passing the process function on this line.

return $(this).on('click', buttonWatch);

So you need to make couple of changes.

  1. Make your function available outside of click event scope
  2. Bind process function as parameter to buttonWatch method when you add on

 $(document).ready(function () { let buttonWatch = function (process) { $(this).off('click'); alert(typeof(process)); // This alerts "function" process(); // The error is thrown here return $(this).on('click', buttonWatch.bind(this,process)); }; $("#loginButton").on('click', function () { function process () { alert("Running a process."); } buttonWatch(process); }); }); 
 <html> <head> <script data-require="jquery@3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body> </html> 

Reference : bind function

As I repeatedly stated, the code runs fine. I only get the weird error from DevTools. In any case, the error is eliminated by using an assignment and DevTools is happy.

$(document).ready(function () {
    let buttonWatch = function (process) {
        $(this).off('click');
        alert(typeof(process)); // This alerts "function"
        let result = process(); // No error is thrown
        return $(this).on('click', buttonWatch);
    };
    $("#loginButton").on('click', function () {
        function process() {
            alert("Running a process.");
        }
        buttonWatch(process);
    });
});

The issue here is that, because the click listener must be reinstantiated upon return, I cannot return the result of the process. So, I coded a better solution using disabled instead of offing the listener at all.

$(document).ready(function () {

    let buttonWatch = function (button, process) {
        $(button).prop("disabled", true);
        let result = process();
        $(button).prop("disabled", false);
        return result;
    };
    $("#loginButton").on('click', function () {
        function buttonProcess() {
            alert("Running a process.");
        }
        buttonWatch(this, buttonProcess);
    });
});

Just for completeness, this set up can be used when passing parameters and requiring that return of the process's results:

$(document).ready(function () {

    // buttonWatch disables and enables clicks around a process
    let buttonWatch = function (button, process) {
        $(button).prop("disabled", true);
        let result = process();
        $(button).prop("disabled", false);
        return result;
    };
    $("#loginButton").on('click', function () {
        function buttonProcess(message) {
            alert(message);
            return false
        }
        buttonWatch(this, function(){return buttonProcess("Running a process.")});
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM