zauberzeug / nicegui

Create web-based user interfaces with Python. The nice way.
https://nicegui.io
MIT License
9.78k stars 580 forks source link

Table (AgGrid) cannot update with a NaN value #126

Closed getzze closed 2 years ago

getzze commented 2 years ago

python 3.10 nicegui v0.9.18

From the example, if I modify the update function to change a cell value to np.nan, the table is not updated anymore:

from nicegui import ui
import numpy as np

table = ui.table({
    'columnDefs': [
        {'headerName': 'Name', 'field': 'name'},
        {'headerName': 'Age', 'field': 'age'},
    ],
    'rowData': [
        {'name': 'Alice', 'age': 18},
        {'name': 'Bob', 'age': 21},
        {'name': 'Carol', 'age': 42},
    ],
}).classes('max-h-40')

def update():
    table.options.rowData[0].age += 1
    table.options.rowData[1].age = np.nan
    table.update()

ui.button('Update', on_click=update)

ui.run()

If the original data has a np.nan, the table is drawn correctly, but update does not work either:

from nicegui import ui
import numpy as np

table = ui.table({
    'columnDefs': [
        {'headerName': 'Name', 'field': 'name'},
        {'headerName': 'Age', 'field': 'age'},
    ],
    'rowData': [
        {'name': 'Alice', 'age': 18},
        {'name': 'Bob', 'age': np.nan},
        {'name': 'Carol', 'age': 42},
    ],
}).classes('max-h-40')

def update():
    table.options.rowData[0].age += 1
    table.update()

ui.button('Update', on_click=update)

ui.run()
falkoschindler commented 2 years ago

Thanks for reporting this issue!

I sort of understand why np.nan causes problems: When being transmitted to the client as JSON, np.nan is converted to a string which can't be interpreted by JavaScript. It works by replacing np.nan with None, with has a JavaScript equivalent null.

It is strange, however, that setting np.nan initially works. That should cause similar problems, but it does only when changing a cell.

Since NiceGUI doesn't do much with grids and basically passes the options to JustPy and AgGrid, I tried to reproduce the problem with a plain JustPy example:

#!/usr/bin/env python3
import justpy as jp
import numpy as np

options = {
    'columnDefs': [
        {'headerName': 'Name', 'field': 'name'},
        {'headerName': 'Age', 'field': 'age'},
    ],
    'rowData': [
        {'name': 'Alice', 'age': 18},
        {'name': 'Bob', 'age': 21},
        {'name': 'Carol', 'age': 42},
    ],
}

def grid_test():
    wp = jp.WebPage()
    grid = jp.AgGrid(a=wp, options=options, classes='max-h-60')

    def update(self, msg):
        grid.options.rowData[0].age += 1
        grid.options.rowData[1].age = np.nan

    jp.Button(text='Update', click=update, a=wp)
    return wp

jp.justpy(grid_test)

The result is the same: When clicking the button, JavaScript complains:

Uncaught SyntaxError: Unexpected token 'N', ..."", "age": NaN}, {"na"... is not valid JSON

So we won't be able to fix the behavior in NiceGUI. Maybe using None is a feasible workaround for you?

getzze commented 2 years ago

Thanks! I was getting this error when importing a pandas DataFrame.

Calling df.fillna('', inplace=True) before table.view.load_pandas_frame(df) solved the issue.