# Multi-Page App Help

**URL:** <https://community.plotly.com/t/multi-page-app-help/20410>\
**Category:** Dash Python\
**Created:** [March 4, 2019, 1:26pm UTC](https://community.plotly.com/t/multi-page-app-help/20410 "2019-03-04T13:26:39Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mdylan2](https://avatars.discourse-cdn.com/v4/letter/m/977dab/32.png) [@mdylan2](https://community.plotly.com/u/mdylan2)\
**Post date:** [March 4, 2019, 1:26pm UTC](https://community.plotly.com/t/multi-page-app-help/20410/1 "2019-03-04T13:26:39Z")

</div>

Hi All,

I started using Dash about a week ago and I absolutely love it! I’m a beginner to programming but I love how intuitive the software is.

I’m posting here because I’m having a lot of trouble getting my multi-page app to work. I followed the directions in [here](https://dash.plot.ly/urls) but I think I’ve gone over my head.

I’m trying to incorporate the hidden div concept described in Example 1 [here](https://dash.plot.ly/sharing-data-between-callbacks) into my main page. Here’s the code I have for my callbacks:

> ```
> # Callback for hidden div storing information from dropdown
> @app.callback(dash.dependencies.Output('hidden', 'children'), [dash.dependencies.Input('gender_dropdown', 'value')])
> def clean_data(value):
> if value is None:
> cleaned_df = df_marks
> else:
> cleaned_df = df_marks[df_marks['gender'] == value]    
> return cleaned_df.to_json(date_format='iso', orient='split')
> 
> # Callback for graph
> @app.callback(
> dash.dependencies.Output(component_id='marks_graph', component_property='figure'),
> [dash.dependencies.Input(component_id='hidden', component_property='children')]
> )
> def update_marks_graph(jsonified_cleaned_data):
> dff = pd.read_json(jsonified_cleaned_data, orient='split')
> return plot_bar(dff,"Marks","bar","Average Score per Test")
> 
> ```

For some reason, it always hits me with this error:  
ValueError: Invalid file path or buffer object type: \<class ‘list’\>. There’s something wrong with the part in which I try to read the JSON file. From what I understand, the only reason it can’t read the JSON file is because my first callback isn’t populating the hidden div!

What’s weird is that I ran the exact same code on a single-page app and that worked like a charm. What’s even weirder is that when I comment out the callback for the graph and refresh the page a couple of times, the hidden div gets populated with data.

The only difference between my code from before is the multi-page structure and my use of Bootstrap Dash code available [here](https://dash-bootstrap-components.opensource.faculty.ai/l/components) for the HTML. I don’t think that the latter should make a difference but I’m not sure.

Can anyone please help me? I’ve been stuck on this problem for a few hours now and really don’t know how to proceed.

Any help would be much appreciated!

---

<div class="post-metadata">

**Author:** ![vantaka2](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/vantaka2/32/5007_2.png) [@vantaka2](https://community.plotly.com/u/vantaka2)\
**Post date:** [March 4, 2019, 6:55pm UTC](https://community.plotly.com/t/multi-page-app-help/20410/2 "2019-03-04T18:55:02Z")

</div>

HI,

It’s hard to say without the code for the entire app, If you can post it, I’ll take a look.

One thing to watch out for is to ensure you don’t repeat id’s within the multi page app.

---

<div class="post-metadata">

**Author:** ![mdylan2](https://avatars.discourse-cdn.com/v4/letter/m/977dab/32.png) [@mdylan2](https://community.plotly.com/u/mdylan2)\
**Post date:** [March 5, 2019, 5:29am UTC](https://community.plotly.com/t/multi-page-app-help/20410/3 "2019-03-05T05:29:29Z")

</div>

Hey @vantaka2,

Thanks for the quick response!

Here’s my file structure:  
| index.py  
| app.py  
| data.csv  
|  
| apps  
|----\_\_init \_\_.py  
|---- comparison.py  
|---- dashboard.py  
|  
| all\_components  
|----\_\_init \_\_.py  
|----navbar.py

I’ve tweaked the code a bit. After a few fixes, I’ve managed to make the graphs work - however, they only work after first selecting a dropdown menu item first. The initial loading of the screen still throws the same error from above when reading the data from the JSON.

I’ve attached the code below. I’ve simplified it a lot so that it’s easier to digest. Let me know what you think.

Thanks a lot!

> **index.py**
> 
> ```
> import dash_core_components as dcc
> import dash_html_components as html
> from dash.dependencies import Input, Output
> 
> from app import app
> from apps import dashboard, comparison
> 
> app.layout = html.Div([
> dcc.Location(id='url', refresh=False),
> html.Div(id='page-content')
> ])
> 
> @app.callback(Output('page-content', 'children'),
> [Input('url', 'pathname')])
> def display_page(pathname):
> if pathname == '/apps/dashboard':
> return dashboard.layout
> elif pathname == '/apps/comparison':
> return comparison.layout
> else:
> return "error 404"
> 
> if __name__ == ' __main__':
> app.run_server(debug=True)
> 
> ```

> **app.py**
> 
> ```
> import dash
> app = dash.Dash( __name__ )
> server = app.server
> app.config['suppress_callback_exceptions']=True
> 
> ```

> **navbar.py**
> 
> ```
> import dash_bootstrap_components as dbc
> 
> navbar = dbc.NavbarSimple(
> children=[
> dbc.NavItem(dbc.NavLink("Overview",href = "/apps/dashboard")),
> dbc.DropdownMenu(
> nav=True,
> in_navbar=True,
> label="Analytical Tools",
> children=[
> dbc.DropdownMenuItem(dbc.NavLink("Student Performance Tracker", href="/apps/comparison")), 
> dbc.DropdownMenuItem(dbc.NavLink("Analytical Tool 2", href="#")),
> dbc.DropdownMenuItem(dbc.NavLink("Analytical Tool 3",href="#")),
> ],
> ),
> dbc.NavItem(dbc.NavLink("Feedback",href = "/apps/feedback")),
> dbc.NavItem(dbc.NavLink("Support",href = "#"))        
> ],
> brand="Dashboard",
> brand_href="#",
> sticky="top",
> dark = True,
> color = 'primary'
> )
> 
> ```

> **dashboard.py**
> 
> ```
> import dash_core_components as dcc
> import dash_html_components as html
> from dash.dependencies import Input, Output
> import dash_bootstrap_components as dbc
> import dash
> import pandas as pd
> import plotly.graph_objs as go
> import numpy as np
> from all_components.navbar import navbar
> 
> from app import app
> 
> """"""""""""""""""""""""""""""
> File Extraction and Editing
> """"""""""""""""""""""""""""""
> df = pd.read_csv('data.csv', sep='\t', encoding='utf-8')
> 
> data manipulation stuff
> 
> print(df_marks.head())
> print(type(df_marks))
> 
> """""""""""""""""""""
> Plot Bar Functions
> """""""""""""""""""""
> 
> def plot_bar(frame,type,chart,title):
> code that plots      
> return {data, layout}
> 
> """""""""""""""""""""
> Body of the Layout
> """""""""""""""""""""
> 
> body = dbc.Container(
> [
> dbc.Row(
> [
> dbc.Col(
> [
> dcc.Dropdown(
> id = "gender_dropdown",
> options = [
> {'label': 'Male','value': 'M'},
> {'label': 'Female', 'value':'F'}
> ],
> placeholder = "Gender",
> style = dict(
> lineHeight = '12px'
> )
> ),
> ]
> ),
> dbc.Col(
> [
> dcc.Graph(id = 'marks_graph')
> ]
> )
> ], className = "mt-4"
> ),
> html.Div(id = "hidden", style = dict(display='None'),children = [])
> ]
> )
> 
> """""""""
> Layout
> """""""""
> 
> layout = html.Div([navbar, body])
> 
> """"""""""""
> Callbacks
> """"""""""""
> 
> @app.callback(dash.dependencies.Output('hidden', 'children'), [dash.dependencies.Input('gender_dropdown', 'value')])
> def clean_data(value):
> if value is None:
> cleaned_df = df_marks
> else:
> cleaned_df = df_marks[df_marks['gender'] == value]    
> return cleaned_df.to_json(date_format='iso', orient='split')
> 
> @app.callback(
> dash.dependencies.Output(component_id='marks_graph', component_property='figure'),
> [dash.dependencies.Input(component_id='hidden', component_property='children')]
> )
> def update_marks_graph(jsonified_cleaned_data):
> dff = pd.read_json(jsonified_cleaned_data, orient='split')
> return plot_bar(dff,"Marks","bar","Average Score per Test")
> 
> ```

> **comparison.py**
> 
> ```
> import dash_core_components as dcc
> import dash_html_components as html
> from dash.dependencies import Input, Output
> import dash_bootstrap_components as dbc
> 
> from app import app
> 
> layout = html.Div([
> html.H3('App 1'),
> dbc.NavItem(dbc.NavLink("Link", href="/apps/dashboard")),
> dcc.Dropdown(
> id='app-2-dropdown',
> options=[
> {'label': 'App 1 - {}'.format(i), 'value': i} for i in [
> 'NYC', 'MTL', 'LA'
> ]
> ]
> ),
> html.Div(id='app-2-display-value'),
> dcc.Link('Go to App 1', href='/apps/dashboard')
> ])
> 
> @app.callback(
> Output('app-2-display-value', 'children'),
> [Input('app-2-dropdown', 'value')])
> def display_value(value):
> return 'You have selected "{}"'.format(value)
> 
> ```

---

<div class="post-metadata">

**Author:** ![MGBpy](https://avatars.discourse-cdn.com/v4/letter/m/e36b37/32.png) [@MGBpy](https://community.plotly.com/u/MGBpy)\
**Post date:** [March 5, 2019, 10:20am UTC](https://community.plotly.com/t/multi-page-app-help/20410/4 "2019-03-05T10:20:02Z")

</div>

That is why I prefer Multi Page App with Divs and not with Tabs. Its easier.

---

<div class="post-metadata">

**Author:** ![mdylan2](https://avatars.discourse-cdn.com/v4/letter/m/977dab/32.png) [@mdylan2](https://community.plotly.com/u/mdylan2)\
**Post date:** [March 5, 2019, 11:19am UTC](https://community.plotly.com/t/multi-page-app-help/20410/5 "2019-03-05T11:19:35Z")

</div>

Just to clarify, my primary issue is in the dashboard.py file.

@MGBpy: What exactly are you referring to when you say tabs? I don’t think I’ve referred to any tabs in my code.

---

<div class="post-metadata">

**Author:** ![mdylan2](https://avatars.discourse-cdn.com/v4/letter/m/977dab/32.png) [@mdylan2](https://community.plotly.com/u/mdylan2)\
**Post date:** [March 5, 2019, 12:38pm UTC](https://community.plotly.com/t/multi-page-app-help/20410/6 "2019-03-05T12:38:09Z")

</div>

Never mind, I figured it out.

Apparently I had to specify the value of the gender\_dropdown as None.

My revised drop down for any one who has this problem in the future:

> ```
> dcc.Dropdown(
> id = "gender_dropdown",
> options = [
> {'label': 'Male','value': 'M'},
> {'label': 'Female', 'value':'F'}
> ],
> placeholder = "Gender",
> value = None,
> style = dict(
> lineHeight = '12px'
> )
> 
> ```

However, I still am curious as to why I need to do this in the multi-page case but not in the single page?

Sorry for wasting all of your guys’ time!

---

<div class="post-metadata">

**Author:** ![MGBpy](https://avatars.discourse-cdn.com/v4/letter/m/e36b37/32.png) [@MGBpy](https://community.plotly.com/u/MGBpy)\
**Post date:** [March 5, 2019, 7:20pm UTC](https://community.plotly.com/t/multi-page-app-help/20410/7 "2019-03-05T19:20:29Z")

</div>

Congrats by fixing it.  
By the way, what is Multi-Page?

---

<div class="post-metadata">

**Author:** ![mdylan2](https://avatars.discourse-cdn.com/v4/letter/m/977dab/32.png) [@mdylan2](https://community.plotly.com/u/mdylan2)\
**Post date:** [March 6, 2019, 4:08am UTC](https://community.plotly.com/t/multi-page-app-help/20410/8 "2019-03-06T04:08:28Z")

</div>

Sorry @MGBpy, I should have been clearer with the description of multi-page.

By multi-page, I mean that the app is organized into different files (app.py, index.py, dashboard.py, etc). Each of these files **can** (doesn’t necessarily have to) correspond to a unique page on a website/app. This allows you to navigate through the app. Also, a multi-page app is useful in organizing large amounts of code and troubleshooting errors in these situations.

[Here’s](https://dash.plot.ly/urls) a better description of the idea and how to do it in Dash.
