Attempting to learn to write bindings--help needed

I’m trying to write a binding that gives me this:

import axios from "axios";

axios.get("http://localhost:3005/characters").then(function (resp) {
      return Promise.resolve((console.log(resp.data)));
    });

I tried something similar to an example from the “Bindings Cookbook” that seemed like it would get me there based on the example:

@module("axios") external get: string => Js.Promise.t<'data> = "get";
let _ = get("http://localhost:3005/characters")->then(resp => resolve(Js.log(resp["data"])))

but it gives me this JavaScript:

// Generated by ReScript, PLEASE EDIT WITH CARE

import * as Axios from "axios";

var Axios$1 = {};

Axios.get("http://localhost:3005/characters").then(function (resp) {
      return Promise.resolve((console.log(resp.data), undefined));
    });

export {
  Axios$1 as Axios,
  
}
/*  Not a pure module */

Running the JavaScript code gives me an error “TypeError: Axios.get” is not a function".

Any help would be greatly appreciated.

Your binding and the generated code look correct, do you have axios installed correctly?

I use axios myself (together with bs-axios) and the generated code is pretty much the same.

It’s likely because you’re using ES6, axios here is a default import, so you need to add a scope("default") like this:

@scope("default") @module("axios") external get: string => Js.Promise.t<'data> = "get";
let _ = get("http://localhost:3005/characters")->then(resp => resolve(Js.log(resp["data"])))
1 Like

Adding @scope(“default”) did the trick!

It took me hours of aimless wanderings to find this solution, which was blind luck when I was about to give up and go back to commonjs. Is this not in the documentation? It seems important.

Maybe here? Interop Cheatsheet | ReScript Language Manual

@scope is in there, but for mundane things like Math.random(), not for using @scope as a hack to get around es6 default import weirdness, as demonstrated here in my working solution:

type pool
@module("pg") @scope("default") @new external pool: unit => pool = "Pool"
import * as Pg from "pg";
var pool = new (Pg.default.Pool)();

Here’s a relevant issue that seems abandoned.

1 Like

There’s an alternative solution:

type axios
@module("axios") external axios: axios = "default"
@send external get: (axios, string) => Js.Promise.t<'data> = "get"

let _ =
  axios->get("http://localhost:3005/characters")
    |> Js.Promise.then_(resp => {
      Js.log(resp["data"])
      Js.Promise.resolve()
    })
1 Like