Black Lives Matter. Please consider donating to Black Girls Code today.

Accessing Upload component contents within a Tab

Hey everyone,

Right now I’m working on a Dash app which has two tabs and each of the tabs has an Upload component into which the user will upload an image. However, right now I have a callback function which renders the tab content depending on the tab but when I try to acces the contents property of the Upload with a callback to show the image in a second child Div of the tab-content, the callback doesnt seem to get triggered:

app.layout = html.Div([
    html.Link(href='/assets/custom.css', rel='stylesheet'),
    html.Div(
        [dcc.Tabs(
            tabs=[
                {'label': tab_tex1t, 'value': 1},
                {'label': tab_text2, 'value': 2},
            ],
            value=1,
            id='tabs',
            vertical=vertical,
            style={
                'height': '100vh',
                'borderRight': 'thin lightblue solid',
                'textAlign': 'left'
            }
        )],
        style={'width': '15%', 'float': 'left'}
    ),
    html.P(id="explanation-p"),
    html.Div(
        [html.Div(),
         html.Div(id="uploaded-image")],
        id="tab-content"
    )
], style={
    'fontFamily': 'Avenir, Sans-Serif',
    'margin-left': 'auto',
    'margin-right': 'auto',
})

@app.callback(Output('tab-content', 'children'), [Input('tabs', 'value')])
def display_content(value):
    if value == 1:

        return [html.Div([
            dcc.Upload(
                id="upload-image",
                children=html.Div([
                    'Drop an image or ',
                    html.A('upload your image')
                ], id="upload-text"),
                style={
                    'width': '50%',
                    'height': '100px',
                    'lineHeight': '60px',
                    'borderWidth': '1px',
                    'borderStyle': 'dashed',
                    'borderRadius': '5px',
                    'textAlign': 'center',
                    'margin': '10px'
                },
                # Allow multiple files to be uploaded
                multiple=True
            )
        ]),
            html.Div()]

    elif value == 2:

        return [html.Div([
            dcc.Upload(
                id="upload-image",
                children=html.Div([
                    'Drop an image or ',
                    html.A('upload your image')
                ], id="upload-text"),
                style={
                    'width': '50%',
                    'height': '100px',
                    'lineHeight': '60px',
                    'borderWidth': '1px',
                    'borderStyle': 'dashed',
                    'borderRadius': '5px',
                    'textAlign': 'center',
                    'margin': '10px'
                },
                # Allow multiple files to be uploaded
                multiple=True
            )
        ]),
            html.Div()]

def parse_contents(contents):
    return html.Img(src=contents, style={'width': 700})

@app.callback(Output('uploaded-image', 'children'),
               [Input('upload-image', 'contents')])
 def update_image(list_of_contents):
     if list_of_contents is not None:
         print(list_of_contents[0])
         children = [
             parse_contents(c) for c in
             zip(list_of_contents)]

         return children

@app.callback(Output('explanation-p', 'children'), [Input('tabs', 'value')])
def display_explanation(value):
    if value == 1:

        return pretrained_explanation_text

    elif value == 2:

        return retrained_explanation_text


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

I have also tried to do both tab value and the upload image contents as inputs in one callback like

@app.callback(Output('uploaded-image', 'children'),
              [Input('tabs', 'value'),
               Input('upload-image', 'contents')])
def update_image(tab, list_of_contents):
    if tab == 1:
        if list_of_contents is not None:
            print(list_of_contents[0])
            children = [
                parse_contents(c) for c in
                zip(list_of_contents)]

            return children
    if tab == 2:
        if list_of_contents is not None:
            print(list_of_contents[0])
            children = [
                parse_contents(c) for c in
                zip(list_of_contents)]

            return children

But to no success… I hope someone know whats up?

Cheers!