Forum

JS Callback issue

11 July 2017 03:58
High all,

I've pretty much followed this workflow to-the-tee (the node based approach):

link

as well as a youtube video that deals with similar functionality.

Strange problem…

After adding my code to the JS; which includes:

requiring logic nodes
append_custom_callback
and adding my custom function

I've checked, double checked and triple checked that I've put the code in the right place and I've compiled as 'copy' AND 'compile' (just to investigate), but when I run the app from the Project Manager, I get a load fail.

I've opened the console window and the error reported is: "Can't find variable: change_cb", which is the name specified in my custom code, for example:

m_logic_n.append_custom_callback("change", change_cb);


I don't know if it's pertinent, but the object in the scene is also 'unselectable', and the outline function isn't working.

Pulling my hair out with this one.

As usual, any help would be sincerely appreciated.

Thanks in advance

Charlie
11 July 2017 11:39
Take a look at this video:
https://www.youtube.com/watch?v=6wI7RgmcK0A
If you still have trouble, go ahead and attach your JavaScript file so we can see it all.
11 July 2017 15:08
Hey Will, thanks for your help in recent days.

This is the video I was referring to in my post (I actually watched it, on you're previous recommendation).

He uses pretty much the same method that I followed, although he uses in and out perams on the Callback node, whereas I don't need them.

The only other thing I've noticed, that's different from various examples, is my js registers my b4w as 'myScene_main', where others seem to say 'myScene_App'.

Here's my JS. Let me know what you think:

"use strict"

// register the application module
b4w.register("my_project_main", function(exports, require) {

// import modules used by the app
var m_app       = require("app");
var m_cfg       = require("config");
var m_data      = require("data");
var m_preloader = require("preloader");
var m_ver       = require("version");


// MY REQUIRE
var m_logic_n   = require("logic_nodes");
// MY REQUIRE



// detect application mode
var DEBUG = (m_ver.type() == "DEBUG");

// automatically detect assets path
var APP_ASSETS_PATH = m_cfg.get_assets_path("my_project");

/**
 * export the method to initialize the app (called at the bottom of this file)
 */
exports.init = function() {
    m_app.init({
        canvas_container_id: "main_canvas_container",
        callback: init_cb,
        show_fps: DEBUG,
        console_verbose: DEBUG,
        autoresize: true
    });
}

/**
 * callback executed when the app is initialized 
 */
function init_cb(canvas_elem, success) {

    if (!success) {
        console.log("b4w init failure");
        return;
    }

    m_preloader.create_preloader();

    // ignore right-click on the canvas element
    canvas_elem.oncontextmenu = function(e) {
        e.preventDefault();
        e.stopPropagation();
        return false;
    };
    
    
    
// MY CUSTOM CALLBACK - THIS IS WHERE THE MAIN ERROR IS BEING CALLED. 'change' IS  THE VARIABLE ID ON MY NODE 
// NOT SURE IF IT'S A PROBLEM WITH MY BRACES OR SEMI COLONS 

m_logic_n.append_custom_callback("change", change_cb);
 



    load();
}

/**
 * load the scene data
 */
function load() {
    m_data.load(APP_ASSETS_PATH + "my_project.json", load_cb, preloader_cb);
}

/**
 * update the app's preloader
 */
function preloader_cb(percentage) {
    m_preloader.update_preloader(percentage);
}

/**
 * callback executed when the scene data is loaded
 */
function load_cb(data_id, success) {

    if (!success) {
        console.log("b4w load failure");
        return;
    }

    m_app.enable_camera_controls();

    // place your code here

// MY CUSTOM FUNCTION 
    function change_cb(in_params, out_params) {
        document.getElementById("OverlayOne").style.display = "block";
// MY CUSTOM FUNCTION
    }
    
    
}


});

// import the app module and start the app by calling the init method
b4w.require("my_project_main").init();
11 July 2017 16:39
I've made a small screen capture video, to show you the processes I'm going through. Maybe it will be easier to see what I'm doing wrong (apologies for the compression, I don't know how to get HD on youtube yet).

https://youtu.be/GRa-r9bWC8I

Let me know if I'm making some horrible mistake.

Thanks again
11 July 2017 19:11
You almost have it. Your problem was scope. Your custom function was declared inside the load_cb function instead of after it.

Should be:
function load_cb(data_id, success) {

     	if (!success) {
     		console.log("b4w load failure");
     		return;
     	}

     	m_app.enable_camera_controls();

     }//this is the closing brace for load_cb
     function change_cb(in_params, out_params) {
     	console.log("My Callback Works!")
        //document.getElementById("OverlayOne").style.display = "block";
    
}

Should not be:
function load_cb(data_id, success) {

    if (!success) {
        console.log("b4w load failure");
        return;
    }

    m_app.enable_camera_controls();

    // place your code here

// MY CUSTOM FUNCTION 
    function change_cb(in_params, out_params) {
        document.getElementById("OverlayOne").style.display = "block";
// MY CUSTOM FUNCTION
    }
    
    
}

Working project example attached if you need it.
11 July 2017 19:30
Sublime text is a code editor that you might like. It is free to try forever or buy it when you want.
https://www.sublimetext.com/
When your cursor is next to a curly brace, the corresponding one is underlined.

It has many cool functions, you might watch a few YouTube videos about it.
11 July 2017 19:47
Wow, thanks… I didn't realise i'd included in the onLoad function.

Starting to make good progress, but as you'll probably know, when you open one door, another closes in your face.

I'm struggling getting the click event to register now (face palm)

I changed the project slightly, so I'm not changing a dynamic div in the HTML (which requires IDs etc). I'm now generating the div within the JS, which works fine.

Now, when I click the cube, I want to change the inner HTML (it's closer to the video you pointed me to, rather than the example on the forum).

When I run the dev.html, the click (or hit) event isn't working… I'm wondering if I've now got node problems, as there's no console errors.

My node goes like:

Entry point >> Switch Select >> JS Callback. ID (string)

Switch select 'miss' and JS Callback 'next' both loop to switch select 'previous'. I have not used any 'in' or 'out' perams in JS callback.

So close, but still not quite there!

Here's my new JS:

"use strict"

// register the application module
b4w.register("showDiv_main", function (exports, require) {

    // import modules used by the app
    var m_app = require("app");
    var m_cfg = require("config");
    var m_data = require("data");
    var m_preloader = require("preloader");
    var m_ver = require("version");
    var m_logn = require("logic_nodes");

    // detect application mode
    var DEBUG = (m_ver.type() == "DEBUG");

    // automatically detect assets path
    var APP_ASSETS_PATH = m_cfg.get_assets_path("showDiv");

    /**
     * export the method to initialize the app (called at the bottom of this file)
     */
    exports.init = function () {
        m_app.init({
            canvas_container_id: "main_canvas_container",
            callback: init_cb,
            show_fps: DEBUG,
            console_verbose: DEBUG,
            autoresize: true
        });
    }

    /**
     * callback executed when the app is initialized 
     */
    function init_cb(canvas_elem, success) {

        if (!success) {
            console.log("b4w init failure");
            return;
        }

        m_preloader.create_preloader();

        // ignore right-click on the canvas element
        canvas_elem.oncontextmenu = function (e) {
            e.preventDefault();
            e.stopPropagation();
            return false;
        };

        console.log("showDiv_cb will be append");
        console.log(showDiv_cb);

        m_logn.append_custom_callback("showDiv", showDiv_cb);


        load();
    }

    /**
     * load the scene data
     */
    function load() {
        m_data.load(APP_ASSETS_PATH + "showDiv.json", load_cb, preloader_cb);
    }

    /**
     * update the app's preloader
     */
    function preloader_cb(percentage) {
        m_preloader.update_preloader(percentage);
    }

    /**
     * callback executed when the scene data is loaded
     */
    function load_cb(data_id, success) {

        if (!success) {
            console.log("b4w load failure");
            return;
        }

        m_app.enable_camera_controls();

       var display_div = document.createElement("div");
    display_div.id = "display_div_id";
    display_div.style.position = "relative";
	display_div.style.color = "green";
	display_div.style.fontSize = "30px";
	display_div.style.fontFamily = "sans-serif";
	display_div.style.fontWeight = "900";
    display_div.innerHTML = "Click the cube to change inner HTML of this div";
    document.body.appendChild(display_div);

    }

    function showDiv_cb(in_params, out_params) {
        console.log("showDiv_cb was called!");
var anchor_elem = document.getElementById("display_div_id");
	anchor_elem.innerHTML = "It worked";
    }

});

// import the app module and start the app by calling the init method
b4w.require("showDiv_main").init();
11 July 2017 21:41
It can be helpful to include a visible feedback that your nodes are working. A show/hide object or animate object work well. Attach your .blend file and I can check your nodes.
11 July 2017 23:15
I think you might be onto something.

I've just tried to use a basic in-scene (no external JS) inherit material logic node, and nothing's working.

I used the technique in my very first B4W test last week link
and it all worked fine. I'm just wondering if there's an issue with the node setup because when I go to open the b4wNodeTree from the 'browse node tree menu', it isn't there any more.

I did replace my first B4W installation (exactly the same location), so perhaps that has something to do with it. I might try a fresh install. If it's still not working, I'll send my blend file for you to have a look at.

Thanks again
12 July 2017 00:02
When replacing your B4W SDK, did you export then re-import your project to the new SDK? I keep a folder called b4w_external to store and back up various files outside of the SDK. Any time I update my SDK, I export all my projects and keep them in the external location to be imported again. You do not need to unzip these files. When you import, you can just select the .zip file.
 
Please register or log in to leave a reply.