[BEGINNER-HELP] I am trying to learn how to use rescript FFI but I am facing issues

Hi Everyone, I am an occasional ocaml developer and I wanted to create a dashboard to replace something I wrote in python (https://github.com/ocaml-bench/sandmark-nightly) because of performance issues.

I wanted to use rescript react to build it but also wanted this to be an activity where I can learn rescript js ffi specially with npm packages.

I am a beginner when it comes to rescript so I might be asking wrong questions.

For example I tried to convert the readCSV function in danfojs mentioned in the getting started section : Getting Started - Danfo.js

And I tried to use the following code to get an object out of the function :

%%raw(`import './App.css';`)
@module("./logo.svg") external logo: string = "default"
@module("danfojs-node") external readCSV: string => {..} = "readCSV"

let a = readCSV("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")

@react.component
let make = () => {
  <div> {a->React.string} </div>
}

I am not able to get anything out of it, any help would be appreciated, Thanks :smiley:

Hi!

  1. The danjo docs mention that for browser apps you should use danfojs and not danfojs-node.
  2. The readCSV method seems to be asynchronous. So you need to wrap the return type in Js.Promise.t
@module("danfojs")
external readCSV: string => Js.Promise.t<{..}> = "readCSV"
  1. When you want to display the CSV or parts of it, you need to transform it to a string first. Here is an example that is close to the one in the docs:
@react.component
let make = () => {
  let (csvString, setCsvString) = React.useState(() => "-")

  React.useEffect0(() => {
    readCSV(
      "https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv",
    )
    ->Js.Promise.then_(csvObj => {
      let csvString = csvObj["describe"]()["print"]()
      setCsvString(_ => csvString)
      Js.Promise.resolve(csvString)
    }, _)
    ->Js.Promise.catch(err => {
      Js.log(err)

      Js.Promise.resolve("")
    }, _)
    ->ignore

    None
  })

  <div> {csvString->React.string} </div>
}

As suggested in the rescript docs, it will be cleaner if you use the new Promise library, but I wrote this one in the playground and did not want to copy the bindings over.

Furthermore, I would suggest to only use {..} for quick prototyping. You most probably want to have a DF.t type instead and write bindings to its object methods.

4 Likes