I am failing to parse a CSV using the JS backend. I am using:
import parsecsv
let filename = "data/heart_100.csv"
var csv: CsvParser
csv.open( filename )
while csv.readRow():
for item in csv.row.items:
echo item
This works fine with nim c -r heart. But when compiled with: nim js heart the browser shows an error like:
Uncaught ReferenceError: fopen is not defined
at open_335544693 (heart.js:4785)
at newFileStream_939525252 (heart.js:5244)
at open_905969746 (heart.js:5558)
at heart.js:7197
What am I missing?
For instance I wrapped a bit of Tabulator, and I managed to load a file from the local file system by means of something like (using karax):
proc createDom(): VNode =
result = buildHtml(tdiv):
h1(text "Tabulator Example", class="title")
button(class="button is-primary"):
text "Load file..."
proc onclick(ev: Event; n: VNode) =
table.setDataFromLocalFile("*.json")
I am trying to do the same but with a different library, so I was wondering about a client side solution to read a local file.
@mantielero You can't read a local file like that in js (at least in recent browsers) because it is a security concern. Imagine any website being able to search and read through any of your files silently.
You would need to do something like suggested here, but in Nim/HTML.
But if you're using Nodejs, then you'll have to either wrap the Nodejs file open lib yourself, or use the library @xigoi suggested.
Thanks for the indications.
In fact, the File API is mostly done (I will file an issue for something that I thing is missing).
Using karax (and bulma), it looks like this:
proc createDom(): VNode =
result = buildHtml(tdiv):
h1(text "Tabulator Example", class="title")
tdiv(class="file"):
label(class="file-label"):
input(class="file-input",`type`="file", name="resume", id="filename"):
proc onChange(ev: Event; n: VNode) =
echo "cambiado"
let element = cast[InputElement](ev.target) # https://nim-lang.org/docs/dom.html#InputElement
let file = cast[kdom.File](element.files[0]) # https://nim-lang.org/docs/dom.html#File
echo file.size
echo file.`type`
echo file.name
let reader = newFileReader() # From dom
reader.readAsText(file) # "./test.csv"
reader.onload = proc (ev:Event) =
echo reader.resultAsString
span(class="file-cta"):
span(class="file-icon"):
italic(class="fas fa-upload")
span(class="file-label"):
text "Chooose a file..."
setRenderer createDom
I also add the following which looks missing in dom:
proc readAsText*(f: FileReader, b: dom.File, encoding = cstring"UTF-8") {.importcpp: "#.readAsText(#, #)".}