How to avoid autosorting data in dcc.Store

Hi all,

I look for a way to avoid sorting dictionary data in dcc.Store. In another word, I want the data keep intact when store it.
Here is an example of using dcc.Store. The order of key names before saving in dcc.Store is [X, 2, 1], however it becomes [1, 2, X] after loading it from Store. Is there any way to avoid sorting it?

import dash
from dash import dcc, html, Input, Output

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Store(id='data_store', data=[]),
    html.Button('Save Input Data', id='save-button'),
    html.Div(id='display-data'),
])

@app.callback(
    Output('data_store', 'data'),
    Input('save-button', 'n_clicks'),
)
def save_input_data(n_clicks):
    stored_data = []
    x = 1
    while x < 3:
        stored_data.append({
            "X": x,
            "2": 2,
            "1": 1,
        })
        x += 1
    print("Before dcc.Store =", stored_data)
    return stored_data

@app.callback(
    Output('display-data', 'children'),
    Input('data_store', 'data')
)
def display_saved_data(saved_data):
    print("After dcc.Store =", saved_data)
    return html.Div(f'Saved Data: {saved_data}')


if __name__ == '__main__':
    app.run_server(debug=True)

Hi @addsc6,

I think that’s not possible because there is no such thing as a ordered dict in JS. I think this link describes your issue.

1 Like

I see. So it depends on which brower used, but I still look for a way to fix it. One way I can think of is to save a list of key names along side with dict data in dcc.Store.

Hi @addsc6

You can use json.dumps() to save it to a string, then json.loads() to turn it back into Python

import dash
from dash import dcc, html, Input, Output
import json

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Store(id='data_store', data=[]),
    html.Button('Save Input Data', id='save-button'),
    html.Div(id='display-data'),
])

@app.callback(
    Output('data_store', 'data'),
    Input('save-button', 'n_clicks'),
)
def save_input_data(n_clicks):
    stored_data = []
    x = 1
    while x < 3:
        stored_data.append({
            "X": x,
            "2": 2,
            "1": 1,
        })
        x += 1
    print("Before dcc.Store =", stored_data)
    return json.dumps(stored_data)

@app.callback(
    Output('display-data', 'children'),
    Input('data_store', 'data')
)
def display_saved_data(saved_data):
    saved_data = json.loads(saved_data)
    print("After dcc.Store =", saved_data)
    return html.Div(f'Saved Data: {saved_data}')


if __name__ == '__main__':
    app.run_server(debug=True)




3 Likes

Indeed, it worked.
Many thanks!

Going deeper into the issue, I find that

it comes from using JSON.parse() function or similar. When the key names are neat numbers, they will be ordered automatically.
When they are string-type, there won’t be any ordering.
You can try it here:

var saved_data = '{"A": 2, "1": 4, "0": 3}';
var parsedData = JSON.parse(saved_data);

console.log(parsedData);