Hello!
I am trying to figure out if there is a way to get data from an external url (that returns a json), but with the data fetched by the client side and then returned to the dash app.
Here is an example that uses data of an external API to make a simple plot. I have commented a working serverside solution, but I need to do the API query on the client side, which I cannot make it work.
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, ClientsideFunction
from dash.exceptions import PreventUpdate
dash_app = dash.Dash(__name__)
server = dash_app.server
def makeplot(df):
if df is None:
X=[]
Y=[]
name=''
tt=''
else:
X=df['Date']
Y=np.log10(df['Cases'])
name='Covid_{0}'.format(df['CountryCode'][0])
tt=df['Country'][0]
fig = go.Figure()
fig.add_trace(go.Scatter(x=X, y=Y,
mode='lines',
name=name))
fig.update_layout(title=tt)
return fig
dash_app.layout = html.Div(
id='app-body',
children=[
html.Div(dcc.Input(id='input-on-submit', type='text')),
html.Button('Submit', id='submit-val'),
html.Div(dcc.Graph(figure=makeplot(None), id='plot',config={'scrollZoom': True})),
dcc.Store(id='store_clientside',data=['123'])
]
)
############################
#Working server-side option#
############################
# @dash_app.callback(
# Output('plot','figure'),
# [Input('submit-val', 'n_clicks')],
# [State('input-on-submit','value')])
# def update_data(n,value):
# if value is None:
# raise PreventUpdate
# url='https://api.covid19api.com/dayone/country/{0}/status/confirmed'.format(value.lower())
# df=pd.read_json(url)
# return makeplot(df)
############################
############################
#####Clientside attemp #####
############################
dash_app.clientside_callback(
ClientsideFunction(
namespace='clientside',
function_name='test_url_fetch'
),
Output('store_clientside', 'data'),
[Input('submit-val', 'n_clicks')],
[State('input-on-submit','value')]
)
@dash_app.callback(
Output('plot','figure'),
[Input('store_clientside', 'data')])
def update_data(data):
if data is None:
raise PreventUpdate
df=pd.read_json(data)
return makeplot(df)
############################
if __name__ == '__main__':
# dash_app.run_server(debug=True)
dash_app.run_server(host='0.0.0.0', port=8080, debug=True)
and the .js
if(!window.dash_clientside) {window.dash_clientside = {};}
window.dash_clientside.clientside = {
test_url_fetch: function (n,country){
console.log(n,country)
return fetch('https://api.covid19api.com/dayone/country/' + country + '/status/confirmed')
}
}
I understand that dash clientside does not handle promises, so this might be a dead end and that is ok, I was just wondering if there is a workaround, or something that could be done in the javascript side that I am missing.
For completeness, this is the error I get on the browser console:
The clientside function clientside.test_url_fetch returned a Promise instead of a value. Promises are not supported in Dash clientside right now, but may be in the future.
Many thanks for the help!