Repository: plotly/dash

Issue:
No data displayed in examples
I cannot get any data to display for any of the examples in either Chrome or Safari on OSX.  The browser comes up, shows the graphs, but they are empty.

![dash](https://cloud.githubusercontent.com/assets/543053/11226571/6fa2ff4c-8d46-11e5-96eb-f759e12b64bb.png)



Discussion:
+1

+1

I saw the same and was getting a javascript error "Cannot call method 'onClose' of null".  Updating the version of socket.io in base.html to "//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.7/socket.io.js" got the examples running for me.  

This was on Windows 7, with eventlet installed.

@jonmoore 's solution worked for me on OSX, thanks!

Issue resolved in [PR4](https://github.com/plotly/dash/pull/4).

thanks for checking this out @rthompsonj @jonmoore @danaki @eyadsibai ! A new version of Dash is now available, completely rewritten, and it works a lot better than this old prototype :) 

Resolving patch:
diff --git a/dash/_callback_context.py b/dash/_callback_context.py
--- a/dash/_callback_context.py
+++ b/dash/_callback_context.py
@@ -1,11 +1,10 @@
 import functools
 import warnings
 import json
-from copy import deepcopy
 import flask
 
 from . import exceptions
-from ._utils import stringify_id, AttributeDict
+from ._utils import AttributeDict
 
 
 def has_context(func):
@@ -147,59 +146,7 @@ def display(btn1, btn2):
                return "No clicks yet"
 
         """
-        triggered = getattr(flask.g, "triggered_inputs", [])
-        triggered = [item["prop_id"] for item in triggered]
-        grouping = getattr(flask.g, "args_grouping", {})
-
-        def update_args_grouping(g):
-            if isinstance(g, dict) and "id" in g:
-                str_id = stringify_id(g["id"])
-                prop_id = f"{str_id}.{g['property']}"
-
-                new_values = {
-                    "value": g.get("value"),
-                    "str_id": str_id,
-                    "triggered": prop_id in triggered,
-                    "id": AttributeDict(g["id"])
-                    if isinstance(g["id"], dict)
-                    else g["id"],
-                }
-                g.update(new_values)
-
-        def recursive_update(g):
-            if isinstance(g, (tuple, list)):
-                for i in g:
-                    update_args_grouping(i)
-                    recursive_update(i)
-            if isinstance(g, dict):
-                for i in g.values():
-                    update_args_grouping(i)
-                    recursive_update(i)
-
-        recursive_update(grouping)
-
-        return grouping
-
-    # todo not sure whether we need this, but it removes a level of nesting so
-    #  you don't need to use `.value` to get the value.
-    @property
-    @has_context
-    def args_grouping_values(self):
-        grouping = getattr(flask.g, "args_grouping", {})
-        grouping = deepcopy(grouping)
-
-        def recursive_update(g):
-            if isinstance(g, (tuple, list)):
-                for i in g:
-                    recursive_update(i)
-            if isinstance(g, dict):
-                for k, v in g.items():
-                    if isinstance(v, dict) and "id" in v:
-                        g[k] = v["value"]
-                    recursive_update(v)
-
-        recursive_update(grouping)
-        return grouping
+        return getattr(flask.g, "args_grouping", [])
 
     @property
     @has_context
diff --git a/dash/_grouping.py b/dash/_grouping.py
--- a/dash/_grouping.py
+++ b/dash/_grouping.py
@@ -14,7 +14,7 @@
 
 """
 from dash.exceptions import InvalidCallbackReturnValue
-from ._utils import AttributeDict
+from ._utils import AttributeDict, stringify_id
 
 
 def flatten_grouping(grouping, schema=None):
@@ -222,3 +222,17 @@ def validate_grouping(grouping, schema, full_schema=None, path=()):
             )
     else:
         pass
+
+
+def update_args_group(g, triggered):
+    if isinstance(g, dict):
+        str_id = stringify_id(g["id"])
+        prop_id = f"{str_id}.{g['property']}"
+
+        new_values = {
+            "value": g.get("value"),
+            "str_id": str_id,
+            "triggered": prop_id in triggered,
+            "id": AttributeDict(g["id"]) if isinstance(g["id"], dict) else g["id"],
+        }
+        g.update(new_values)
diff --git a/dash/dash.py b/dash/dash.py
--- a/dash/dash.py
+++ b/dash/dash.py
@@ -61,11 +61,7 @@
 from . import _watch
 from . import _get_app
 
-from ._grouping import (
-    flatten_grouping,
-    map_grouping,
-    grouping_len,
-)
+from ._grouping import flatten_grouping, map_grouping, grouping_len, update_args_group
 
 from . import _pages
 from ._pages import (
@@ -1431,6 +1427,14 @@ def dispatch(self):
             inputs_state = inputs + state
             inputs_state = convert_to_AttributeDict(inputs_state)
 
+            # update args_grouping attributes
+            for g in inputs_state:
+                # check for pattern matching: list of inputs or state
+                if isinstance(g, list):
+                    for pattern_match_g in g:
+                        update_args_group(pattern_match_g, changed_props)
+                update_args_group(g, changed_props)
+
             args_grouping = map_grouping(
                 lambda ind: inputs_state[ind], inputs_state_indices
             )


Test patch:
diff --git a/tests/assets/grouping_app.py b/tests/assets/grouping_app.py
--- a/tests/assets/grouping_app.py
+++ b/tests/assets/grouping_app.py
@@ -39,7 +39,7 @@ def grouping_app():
         ),
         dict(
             items=dict(
-                all=State({"item": ALL}, "children"),
+                all=State({"id": ALL}, "children"),
                 new=State("new-item", "value"),
             ),
             triggers=[Input("add", "n_clicks"), Input("new-item", "n_submit")],
@@ -64,11 +64,11 @@ def edit_list(items, triggers):
             html.Div(
                 [
                     dcc.Checklist(
-                        id={"item": i, "action": "done"},
+                        id={"id": i, "property": "done"},
                         options=[{"label": "", "value": "done"}],
                         style={"display": "inline"},
                     ),
-                    html.Div(text, id={"item": i}, style=style_todo),
+                    html.Div(text, id={"id": i}, style=style_todo),
                 ],
                 style={"clear": "both"},
             )
diff --git a/tests/integration/callbacks/test_wildcards.py b/tests/integration/callbacks/test_wildcards.py
--- a/tests/integration/callbacks/test_wildcards.py
+++ b/tests/integration/callbacks/test_wildcards.py
@@ -421,10 +421,10 @@ def assert_callback_context(items_text):
             items=dict(
                 all=[
                     {
-                        "id": {"item": i},
+                        "id": {"id": i},
                         "property": "children",
                         "value": text,
-                        "str_id": stringify_id({"item": i}),
+                        "str_id": stringify_id({"id": i}),
                         "triggered": False,
                     }
                     for i, text in enumerate(items_text[:-1])