question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unable to link download CSV button to datatable using CustomJS

See original GitHub issue

I am attempting to follow the Export Data to CSV demo by linking a download Button to a datatable. It is currently not working in Jupyter Notebook or in my Flask/Bokeh web app. Here is my environment:

  • Python 2.7.12 :: Anaconda 4.1.1 (64-bit)
  • numpy==1.11.1
  • pandas==0.18.1
  • bokeh==0.12.4
  • Windows 7, Chrome

And here is a code snippet:

import pandas as pd
import numpy as np
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import DataTable, NumberFormatter, TableColumn, Button
from bokeh.plotting import show
from bokeh.layouts import column

df = []
for ii in range(1, 11):
    df.append({'x': ii, 'y': 1000 * np.random.rand()})
df = pd.DataFrame(df)

source = ColumnDataSource(data=df)

columns = [
    TableColumn(field='x', title='Col 1'),
    TableColumn(field='y', title='Col 2',
                formatter=NumberFormatter(format='$0,0.00',
                                          text_align='right')),
]

dt = DataTable(source=source, columns=columns, width=500, height=200, row_headers=False)

callback = CustomJS(args=dict(source=source), code="""
            var data = source.get('data');
            var filetext = 'x,y\n';
            for (i=0; i < data['x'].length; i++) {
                var currRow = [data['x'][i].toString(),
                               data['y'][i].toString().concat('\n')];

                var joined = currRow.join();
                filetext = filetext.concat(joined);
            }

            var filename = 'data.csv';
            var blob = new Blob([filetext], { type: 'text/csv;charset=utf-8;' });

            //addresses IE
            if (navigator.msSaveBlob) {
                navigator.msSaveBlob(blob, filename);
            }

            else {
                var link = document.createElement("a");
                link = document.createElement('a')
                link.href = URL.createObjectURL(blob);
                link.download = filename
                link.target = "_blank";
                link.style.visibility = 'hidden';
                link.dispatchEvent(new MouseEvent('click'))
            }
        """)
button = Button(label='Download', button_type='success', callback=callback)

show(column(dt, button))

Here is the output I get in my Jupyter notebook: untitled

But, when I click the download Button nothing happens. Here is the error message that I get in my console:

Uncaught SyntaxError: Invalid or unexpected token
    at new Function (<anonymous>)
    at cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js:11
    at r.CustomJS.r._make_func (cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js:11)
    at r.func (cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js:11)
    at r.CustomJS.r.execute (cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js:11)
    at e.i.AbstractButtonView.e.change_input (cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.js:1)
    at e.i.ButtonView.e.change_input (cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.js:1)
    at HTMLDivElement.dispatch (cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js:66)
    at HTMLDivElement.o.dispatch (cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.4.min.js:171)
    at HTMLDivElement.m.handle (cdn.pydata.org/bokeh/release/bokeh-0.12.4.min.js:65)

Here is the error message I get when I run my Flask/Bokeh app on localhost:

Uncaught TypeError: Cannot read property '0' of undefined
    at r.eval (eval at <anonymous> (bokeh-0.12.4.min.js:11), <anonymous>:8:42)
    at r.CustomJS.r.execute (bokeh-0.12.4.min.js:11)
    at e.i.AbstractButtonView.e.change_input (bokeh-widgets-0.12.4.min.js:1)
    at e.i.ButtonView.e.change_input (bokeh-widgets-0.12.4.min.js:1)
    at HTMLDivElement.dispatch (bokeh-0.12.4.min.js:66)
    at HTMLDivElement.o.dispatch (bokeh-widgets-0.12.4.min.js:171)
    at HTMLDivElement.m.handle (bokeh-0.12.4.min.js:65)

Not sure if this is a JS error or a Bokeh bug.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
covellozcommented, Mar 7, 2017

Hey Ian,

I know this issue is closed and you figured out a work-around by using a separate file. However, I figured out the exact cause of the error Uncaught SyntaxError: Invalid or unexpected token

It is because you were not escaping the \n character. Because “code” [in the callback] is a string in the python code, you need to escape the backlash: \\n

Thanks for writing up this code! It will be extremely helpful for me to have the ability to download the data to CSV.

import pandas as pd
import numpy as np
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import DataTable, NumberFormatter, TableColumn, Button
from bokeh.plotting import show
from bokeh.layouts import column

df = []
for ii in range(1, 11):
df.append({'x': ii, 'y': 1000 * np.random.rand()})
df = pd.DataFrame(df)

source = ColumnDataSource(data=df)

columns = [TableColumn(field='x', title='Col 1'),TableColumn(field='y', title='Col 2',formatter=NumberFormatter(format='$0,0.00',text_align='right'))]

dt = DataTable(source=source, columns=columns, width=500, height=200, row_headers=False)

callback = CustomJS(args=dict(source=source), code="""
var data = source.data;
var filetext = 'x,y\\n';

for (i=0; i < data['x'].length; i++) {
	var currRow = [data['x'][i].toString(), data['y'][i].toString().concat('\\n')];
	var joined = currRow.join();
	filetext = filetext.concat(joined);
}	

var filename = 'data.csv';
var blob = new Blob([filetext], { type: 'text/csv;charset=utf-8;' });

//addresses IE
if (navigator.msSaveBlob) {
	navigator.msSaveBlob(blob, filename);
}

else {
	var link = document.createElement("a");
	link = document.createElement('a')
	link.href = URL.createObjectURL(blob);
	link.download = filename
	link.target = "_blank";
	link.style.visibility = 'hidden';
	link.dispatchEvent(new MouseEvent('click'))
}
""")

button = Button(label='Download', button_type='success', callback=callback)

show(column(dt, button))
2reactions
bryevdvcommented, Jan 13, 2017

Nevermind, this was a silly mistake on my end…

Happens to us all 😃 Can you describe what happened, in case it is also useful to someone else in the future?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Python-Bokeh application:Unable to export updated data from ...
After refreshing the dataframe,the user will need to export the dataframe to his local system(in csv format) by clicking a BOKEH BUTTON widget....
Read more >
CSV Export button not working — DataTables forums
I'm using jquery 3.3.1 & buttons 1.5.1. Excel & PDF appear to work in Chrome while CSV just saves a blank file without...
Read more >
Advanced settings | WP Data Access
I went here to get the CSS and JS: https://datatables.net/download/release and tried to add them via header tags or via wp_enqueue. Neither way ......
Read more >
EA Advanced Data Table | Essential Addons for Elementor
To do so, first hit the 'Export' button. EA Advanced Data Table will be downloaded in CSV format. Advanced Data Table. How to...
Read more >
Linking objects in Panel — Panel v0.14.2
jslink : high-level API to link objects via JS code. obj.jscallback : a lower-level API to define arbitrary Javascript callbacks. At the end...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found