2

This question may be a bit confusing, so let me give you some background. Eel is a Python module where you can take functions made in Python and use them in Javascript, and vice versa. What I want to do is take a json made from a Python function, put it in Javascript, and make a table based on the json that was taken from the Python side. Here's an example.

python.py

def json_example():
    json = [
        {
            "key": "value1"
        },
        {
            "key": "value2"
        }
    ]
    return json

js.html

<body>
    <div></div>
</body>
<script>
    function js_example() {
        # This is where the function from Python is called
        var json_obj = eel.json_example();
        var tbl = $("<table/>").attr("id", "example_table");
        $("div").append(tbl);
        for(var i=0; i<json_obj.length; i++){
            var tr="<tr>";
            var td="<td>"+obj[i]["key"]+"</td></tr>";
            $('#example_table').append(tr+td);
        }
    }

I tested both of these functions out separately with a few changes and they both work. However, here's where the problem starts. For some reason, the Javascript part is not getting anything from the function it calls from the Python code. the variable "json_obj" should be equal to the json I made in the Python function, but for some reason the return value of the function isn't creating tangible data that can be manipulated in the Javascript, basically returning nothing. And the eel transfer itself works as well. If you replace "return" with "print", it will print the json in the console.

Also, please don't tell me to just put the json itself in the Javascript. I have a reason for needing the json to come from the Python side.

So basically, here's my question: how do you get a Python function to create a value that can be manipulated in Javascript?

Bjorn Liza
  • 109
  • 1
  • 11
Jerry Bi
  • 321
  • 6
  • 24

2 Answers2

2

The problem is that when eel exposes a function what it actually does is it creates a new function that will return a promise containing the return value of your python function.
So you should have something like this instead:

let json_obj = ''; 
eel.json_example()(x => json_obj = x);

If you need more help on callbacks, refer to https://github.com/ChrisKnott/Eel.

alexfertel
  • 925
  • 1
  • 9
  • 22
0

Convert to json within Python if you're calling Python to begin with and send json to JS in the return value.

See: https://github.com/ChrisKnott/Eel/tree/master/examples/03%20-%20sync_callbacks

To do a synchronous operation that will take time to complete in Python and then return a value into JS, use;

let n = await eel.py_random()();

which is really

let mySlowReturnValueFromPython = await eel.myExposedPythonFunction()();

In fact I tried to code in my own promises and I was getting back garbage that looked like eel promises. The browser maintains a thread while you call this way, so the user can kick off a long Python operation and still interact with the GUI.

I'd note that you can still call things that update the GUI asynchronously. If you have a bunch of Python functions which return ready-made HTML as I do, then you can kick them all off in a row without waiting and they will update the divs whenever they return. I use this;

eel.expose(updateDiv);
function updateDiv(newData, divToUpdate)
{
var fieldToUpdate = document.getElementById(divToUpdate)
fieldToUpdate.innerHTML = newData
}

Then I call my Python function which gets the data synchronously, packs it up into a ready-made HTML chunk for the GUI, and then calls updateDiv from Python. I'm actually really enjoying the power that this "ping pong" interaction between a synchronous codebase and an asynchronous one give me when working with a GUI. Worlds better than arfing about with TK.

I hope this helps you and you can struggle less with it than I did. Once you understand how this works, Eel is really great. It apparently handles sync for you, just hand it a blank callback (or whatever black magic that is). What a great lib! Eel is just perfect for locally hosted GUI's. I'd like to see a better GUI framework than HTML/CSS/JS - the truth is that there really isn't one, those things are so well tested and stable, with so many available examples for whatever you could want to create.

I'd really like to see this become the native Python GUI solution. Browsers are extremely cross-platform and the only problem to solve when porting becomes interfacing the browser to Python.