# AgGrid: getting the data type of a column or cell

**URL:** https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762
**Category:** Dash Python
**Created:** [December 7, 2023, 4:09pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762 "2023-12-07T16:09:29Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 4:09pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/1 "2023-12-07T16:09:29Z")

</div>

I am having trouble extracting the data-type from an AgGrid column dynamically. in my case, the AgGrid starts with no data (i.e: `rowData = []`), meaning I can’t just iterate over `rowData` and extract the `type` of the value stored at any field, and I populate the data with a callback to `rowTransaction` from a button click (essentially, add rows when a user specifies). Additionally, my AgGrid is a subcomponent of a custom AIO (All-in-One) component because I want to re-use the grid in different places in my app and re-use the callbacks as I don’t want to re-write them for every similar grid I create; i.e: the layout of my grid doesn’t change (i.e: it’s placement in a div with a few other buttons and multi-selects remains the same) and the interactivity (callbacks) the grid has with other subcomponents (like buttons and multi-selects) remains the same, but the data/rows I am trying to display will change (hence, why I thought an AIO would be appropriate).

In javascript (see [here](https://www.ag-grid.com/javascript-data-grid/cell-data-types/) ), one can define cell-datatypes (and I can see how this would be easy to map to a python data type (i.e: “text → str()”, and "number → int/float etc…), but there doesn’t seem to be an analog in the Dash AgGrid component properties. I found that in `columnDefs` there is a property called `type`, but that doesn’t appear to be useful information (or straight forward to derive the data type of a cell or column dynamically).

Additionally, I tried passing additional context in the AIO components class constructor:

```python
def __init__ (self, row_format, AgGrid_props=None, button_props=None, <remaining_subcomponents_props>=None)

```

where, `row_format = {"field1":str, "field2":int}` is the information I want to utilize, but I seem to be not able to pass class properties to callbacks, as the `@callback` decorator dictates the outputs and inputs of the callback, and an error is thrown if I pass `self` to the callback.

What is the best way to go about fixing this issue?

---

<div class="post-metadata">

### Author: ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)
#### Post date: [December 7, 2023, 4:25pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/2 "2023-12-07T16:25:24Z")

</div>

Hello @dave0,

Welcome to the community!

Dash AG Grid is currently using v29.3.5 of the underlying AG Grid, as such, there is no inferring of data types by the grid, this was introduced in v30. As such, there are some breaking changes in how applications work, the team is working hard to update the document examples to make sure that users are aware of some of the things they will encounter by upgrading to v31.

So, currently, there is no way to see what data type there is unless you define it.

Also, I’m not entirely sure you would be able to see this in a callback, because `columnDefs` goes one direction and gets adjusted by the grid after being passed it. You could however use the api to be able to pull this info from the grid, once v31 is released from dag.

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 5:08pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/3 "2023-12-07T17:08:30Z")

</div>

Hi @jinnyzor , thank you for the reply. Is there a way in my AIO to pass additional properties that can be used in callbacks? for example, AIO components are structured such that I need to pass sucomponent props to the class constructor. Can I define custom props for the AIO component itself, or is this not possible since the component inherits from a Dash component? I tried adding additional props to a subcomponent prop and threw a TypeError as it was not defined property of the component’s class. For example, is there a way to access `row_format` in a callback (maybe by specifying `State("ids.myComponent(MATCH)", "row_format")`?

Another thing I tried was adding a dcc.Store to the AIO component, but the app did not render after doing this and instead I got the `Error Loading` message in the top left hand corner of the web page when it got rendered

---

<div class="post-metadata">

### Author: ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)
#### Post date: [December 7, 2023, 5:14pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/4 "2023-12-07T17:14:24Z")

</div>

Correct, AIO components can only have props from the underlying components.

If done correctly, you shouldnt have an error with it.

In my personal use, I have functions that return the configured grid that falls into pattern-matching realms, thus I only have a pattern-matching callback to deal with.

This is incorrect:  
`State("ids.myComponent(MATCH)", "row_format")` → `State(ids.myComponent(MATCH), "row_format")` would be proper, if the `row_format` existed as a prop.

To gain access to additional properties from the grid, you have access in the clientside by using the `dash_ag_grid.getApi` method and passing a stringified id to find the grid’s api. Then you can pull whatever from the api.

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 5:24pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/5 "2023-12-07T17:24:12Z")

</div>

> [@jinnyzor](#):
>
> dash\_ag\_grid.getApi

Thank you for the reply! It’s helpful to know. I cannot find `getApi` in the dash AgGrid reference. Can you please point me to it?

Thanks!

---

<div class="post-metadata">

### Author: ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)
#### Post date: [December 7, 2023, 5:26pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/6 "2023-12-07T17:26:42Z")

</div>

Sure, take a look at this example:

> **[Row Dragging - External Dropzone | Dash for Python Documentation | Plotly](https://dash.plotly.com/dash-ag-grid/row-dragging-external-dropzone)**
>
> Drag and drop rows in an external dropzone - Including grid to grid

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 5:30pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/7 "2023-12-07T17:30:12Z")

</div>

Thanks! Also, I am guessing global variables inside the callback are a no-no? for example within the callback declare `global row_format` and then outside of the AIO define `row_format = {"field1":str, "field2":int}` ?

---

<div class="post-metadata">

### Author: ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)
#### Post date: [December 7, 2023, 5:33pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/8 "2023-12-07T17:33:05Z")

</div>

Global variables are useful if you are the only user using the application and you will only have one session in use.

If you plan to not do the above, then you should avoid them and only declare things within the scope of the callback. Return any variables to be picked up by the app with functions.

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 6:03pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/9 "2023-12-07T18:03:51Z")

</div>

Ok! That’s what I thought. Do you know why I get `Error loading layout` when I try to use a `dcc.Store` in my AIO component? I don’t think I have the technical background to understand why.

I am getting the following error:

```auto
File python3.11/json/encoder.py", line 180, in default
    raise TypeError(f'Object of type {o. __class__. __name__ } '
TypeError: Object of type type is not JSON serializable

```

With stack trace:

```auto
Traceback (most recent call last):
  File "/Users/<user>/opt/miniconda3/lib/python3.11/site-packages/flask/app.py", line 1455, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/<user>/opt/miniconda3/lib/python3.11/site-packages/flask/app.py", line 869, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/<user>/opt/miniconda3/lib/python3.11/site-packages/flask/app.py", line 867, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/<user>/opt/miniconda3/lib/python3.11/site-packages/flask/app.py", line 852, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/<user>/opt/miniconda3/lib/python3.11/site-packages/dash/dash.py", line 733, in serve_layout
    to_json(layout),
    ^^^^^^^^^^^^^^^
  File "/Users/<user>opt/miniconda3/lib/python3.11/site-packages/dash/_utils.py", line 26, in to_json
    return to_json_plotly(value)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/<user>/opt/miniconda3/lib/python3.11/site-packages/plotly/io/_json.py", line 143, in to_json_plotly
    json.dumps(plotly_object, cls=PlotlyJSONEncoder, **opts), _swap_json
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/<user>/opt/miniconda3/lib/python3.11/json/ __init__.py", line 238, in dumps
    **kw).encode(obj)
          ^^^^^^^^^^^
  File "/Users/<user>opt/miniconda3/lib/python3.11/site-packages/_plotly_utils/utils.py", line 59, in encode
    encoded_o = super(PlotlyJSONEncoder, self).encode(o)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/<user>/opt/miniconda3/lib/python3.11/json/encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/<user>i/opt/miniconda3/lib/python3.11/json/encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
  File "/Users/<user>/opt/miniconda3/lib/python3.11/site-packages/_plotly_utils/utils.py", line 136, in default
    return _json.JSONEncoder.default(self, obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/<user>/opt/miniconda3/lib/python3.11/json/encoder.py", line 180, in default
    raise TypeError(f'Object of type {o. __class__. __name__ } '
TypeError: Object of type type is not JSON serializable

```

---

<div class="post-metadata">

### Author: ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)
#### Post date: [December 7, 2023, 6:14pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/10 "2023-12-07T18:14:37Z")

</div>

Without seeing how you are spinning it up, I’m not sure. Something seems to be crashing it.

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 6:18pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/11 "2023-12-07T18:18:21Z")

</div>

`python src/app.py`

---

<div class="post-metadata">

### Author: ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)
#### Post date: [December 7, 2023, 6:28pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/12 "2023-12-07T18:28:36Z")

</div>

Can I see your AIO definition?

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 6:38pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/13 "2023-12-07T18:38:13Z")

</div>

Sure!

```python
import uuid
from dash import Output, Input, State, html, dcc, MATCH, callback, no_update
import dash_ag_grid as dag
import dash_mantine_components as dmc

class ConstraintTableAIO(html.Div):

    # Set of functions to create pattern-matching callbacks of the subcomponents:
    class Ids:
        """
            IDS: Makes the subcomponent id elements able to be pattern matched with Dash's `MATCH`.
        """
        # Store to include additional information about the row format of the grid:
        store = lambda aio_id: {
            "component": "ConstraintTableAIO",
            "subcomponent":"store",
            "aio_id":aio_id
        }

        # Button to add constraints to the AgGrid
        addconstr = lambda aio_id: {
            "component": "ConstraintTableAIO",
            "subcomponent":"addconstr",
            "aio_id":aio_id
        }

        # Multi-select to define the constriant
        selector = lambda aio_id: {
            "component": "ConstraintTableAIO",
            "subcomponent": "selector",
            "aio_id": aio_id
        }

        # AgGrid object to visualize the user's choices
        grid = lambda aio_id: {
            "component":"ConstraintTableAIO",
            "subcomponent": "grid",
            "aio_id": aio_id
        }

        # A button to clear selections from the table
        remconstr = lambda aio_id: {
            "component":"ConstraintTableAIO",
            "subcomponent": "remconstr",
            "aio_id": aio_id
        }
    
    # Make the ids public:
    ids = Ids
    
    # Define the arguments of the All-in-One component:
    def __init__ (
            self,
            store_props,
            addbtn_props=None,
            selector_props=None,
            grid_props=None,
            rembtn_props=None,
            aio_id=None
    ):

        # Define the aio_id:
        if aio_id is None:
            aio_id = str(uuid.uuid4())
            
        # Get all of the properties for each subcomponent:
        addbtn_props = addbtn_props.copy() if addbtn_props else {}
        selector_props = selector_props.copy() if selector_props else {}
        grid_props = grid_props.copy() if grid_props else {}
        rembtn_props = rembtn_props.copy() if rembtn_props else {}
        store_props = store_props.copy() # required!
        # Define the component's layout:
        super(). __init__ (
            [
                dcc.Store(id=self.ids.store(aio_id),**store_props),
                dmc.Group(
                    children=
                    [
                        dmc.Button(id=self.ids.addconstr(aio_id), **addbtn_props),
                        dmc.Space(w="sm"),
                        dmc.MultiSelect(id=self.ids.selector(aio_id), **selector_props)
                    ],
                    align="center"
                ),
                dag.AgGrid(id=self.ids.grid(aio_id), **grid_props),
                dmc.Space(mb=5),
                dmc.Button(id=self.ids.remconstr(aio_id), **rembtn_props)
            ]
        )

```

Here is the callback I am attempting to use to fill a row properly and allow a row\_format to be specified at run-time:

```auto
@callback(
        Output(ids.grid(MATCH), "rowTransaction"),
        Output(ids.selector(MATCH), "value"),
        Input(ids.addconstr(MATCH), "n_clicks"),
        State(ids.selector(MATCH), "value"),
        State(ids.selector(MATCH), "rowData"),
        State(ids.store(MATCH), "data")
        # prevent_initial_call=True
    )
    def add_row_to_grid(n,value,data,store):
        """
            ADD_ROW_TO_GRID: Adds a new row to the grid. Conforms to the row_format.
        """
        if n:
            field = store["selector_field"]
            field_dtype = store["row_format"][field]
            default_row = store["row_format"].copy()
            if data is not None and data!=[]:
                
                # All the values already added to a row in the grid:
                exists = [d[field] for d in data]
                
                # This prevents us from adding the same selection twice.
                # A user will have to clear the table via a selection and clear action first.
                vals = [v for v in value if v not in exists]
            else:
                vals = value
                

            # make sure to cast v to the proper type
            rows = [default_row.update({field:field_dtype(v)}) for v in vals]
            txn = {"add":rows}
            value = []
            return txn, value
        return no_update,no_update

```

here, the values stored in`dmc.MultiSelect` only change the value of a specified AgGrid `field` and the rest of the row fields have default values. In the `dcc.Store`, `"data"` contains a dictionary: `{"row_format":{"field1":str,"field2":<default_float_value>}, "selector_field":"field1"}`

additionally, I tried changing `modified_timestamp` in the `store_props` I pass in to something other than `-1`.

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 7:00pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/14 "2023-12-07T19:00:24Z")

</div>

Follow up: I think it is a problem with `to_json_plotly`. Before creatiing my AIO component, I had already created existing UI elements that I was playing around with. I used the `to_json_plotly()["props"]` function to retrieve their properties before passing them into my AIO.

For example, I had a button called `add_constr` and wanted to copy it’s properties rather than re-write them:

```python
addbtn_props = add_constr.to_json_plotly()["props"]
del addbtn["id"]

aio = ConstraintTableAIO(addbtn_props=addbtn_props, etc...)

```

---

<div class="post-metadata">

### Author: ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)
#### Post date: [December 7, 2023, 7:10pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/15 "2023-12-07T19:10:52Z")

</div>

Ah, yeah, your error message looked similar to that.

I think the plotly json string is a little more complex then just regular props, that might be why you are running into this issue.

I think it is at least one layer in:

`aio = ConstraintTableAIO(addbtn_props=addbtn_props['props'], etc...)`

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 7:15pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/16 "2023-12-07T19:15:05Z")

</div>

ok! Actually, to clarifiy I am passing a `dict` of props in for the `dcc.Store` properties and it is complaining. The other properties use the `to_json_plotly()` method and the app renders if I remove the `dcc.Store` subcomponent from the AIO

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 7:34pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/17 "2023-12-07T19:34:24Z")

</div>

@jinnyzor , I solved my issue by replacing the `dcc.Store` with a hidden `html.Div` and passing a string representation of the `row_format` to the `children` property of the Div. In the callback, I call `eval()` on the string stored in `children` to extract my static info as a dictionary

---

<div class="post-metadata">

### Author: ![jinnyzor](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/jinnyzor/32/21194_2.png) [@jinnyzor](https://community.plotly.com/u/jinnyzor)
#### Post date: [December 7, 2023, 7:41pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/18 "2023-12-07T19:41:04Z")

</div>

I would use something other than eval…

You should probably do `json.loads` since you are expecting a list. 😉

Eval is very dangerous, could remove everything on your computer. 😛

---

<div class="post-metadata">

### Author: ![AnnMarieW](https://avatars.discourse-cdn.com/v4/letter/a/ec9cab/32.png) [@AnnMarieW](https://community.plotly.com/u/AnnMarieW)
#### Post date: [December 7, 2023, 7:42pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/19 "2023-12-07T19:42:49Z")

</div>

@dave0 here is more info

> [@Writing Secure Dash Apps - Community Thread](https://community.plotly.com/t/writing-secure-dash-apps-community-thread/54619):
>
> Hey folks – Here’s a community thread to kick off security-related patterns & concerns when writing Dash apps. The Dash framework itself is architected in a way to avoid many security issues outright (like many XSS issues encountered when rendering arbitrary HTML) and our commercial Dash Enterprise platform provides strict security controls beyond the application code (with authorization, authentication, sandboxing apps in containers away from the host server, security audits, and more). Howe…

---

<div class="post-metadata">

### Author: ![dave0](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dave0](https://community.plotly.com/u/dave0)
#### Post date: [December 7, 2023, 7:43pm UTC](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762/20 "2023-12-07T19:43:54Z")

</div>

ah! wow I see what you mean! The only annoyance is json cannot handle `str` or object when calling `json.loads` on the string representation. I am trying to specify a type

[Next page](https://community.plotly.com/t/aggrid-getting-the-data-type-of-a-column-or-cell/80762.md?page=2)
