A few small questions

There’s React.Children, module with map, forEach and other stuff.

1 Like

Link to the bindings: https://github.com/rescript-lang/rescript-react/blob/0f74265112bc8b725d361634fd49392a0ae29707/src/React.res#L56

How would I do if (a instanceof Error) ... in ReScript?

You can do it only with %raw

Why would you need to do a instanceof Error? Perhaps there is a more idiomatic way of doing what you are trying to accomplish.

1 Like

To add to this, note that this isn’t just a ReScript thing. In ReactJS you should treat children as opaque and use the React.Children functions.

3 Likes

Thank you, this clarified it for me.

@yawaramin

The cors API returns an Error if something fails, otherwise some success object:

type corsFn = (Next.Request.t, Next.Response.t, t => unit) => unit

@module("cors")
external create: {..} => corsFn = "default"

let allow = (corsFn: t, req: Next.Request.t, res: Next.Response.t) =>
  Promise.make((resolve, _) =>
    corsFn(req, res, result => {
      //if (result instanceof Error) {
      //reject(result)
      //return
      //}
      resolve(. result)
    })
  )

Which cors API is this? Can you point to some documentation or post a JavaScript example which shows the behaviour?

Thank you @yawaramin. I appreciate your effort to help but we’re focusing too much on the specifics. Imagine that such an API exists - how do I tackle it with ReScript? After all, it’s ReScript that I need help wrapping my head around, not some bad API specification!

Just asking because I’ve never come across any API that actually returns an Error object on failure (instead of throwing an exception or returning null or calling an onError handler).

Actually it’s a good pattern in typescript, because this way you can describe possible errors of an API with typesystem. It’s kind of an alternative of result type.

But don’t forget difference between error and exception flow, when use something like this.

For this case, I’d either create a function to test instnanceof Error, or a function to convert it to ReScript’s result type. But you need to use %raw for the instanceof anyway.

1 Like

So basically (in TypeScript terms) type Result<A> = A | Error? OK, I get it. Imho not a great approach (what happens when A is supposed to be Error) but can of course be handled with %raw.

No, in this approach you directly type data or a function return value without creating result type. In this case the code using this approach looks very similar to go, where after every function call you have an if statements, handling possible errors.
To be able to map over result in typescript people usually use a third-party library with either-monad. I personally used sweet-monads/either at master · JSMonk/sweet-monads · GitHub

I’ve never seen such a problem using this approach.

Is --save-dev correct for rescript?

I’m using npm ci --omit=dev when building my docker image and it can’t run because the rescript module doesn’t exist. I think this is an error in the documentation!?

Usually it’s correct to save in dependencies as it has modules which need to be used at runtime. The docs should probably be fixed here.

1 Like

Thanks.

How do I merge two dictionaries in ReScript?

I’m used to doing {…a,…b} but ReScript is only allowing one spread operator it seems.

If you are talking about Js.Dict.t, you would need to write your own binding to Object.assign.

let dictA = [("1", 1), ("2", 2), ("3", 3)]->Js.Dict.fromArray
let dictB = [("4", 4), ("5", 5), ("6", 6)]->Js.Dict.fromArray

@val
external assign: (Js.Dict.t<'a>, Js.Dict.t<'a>) => Js.Dict.t<'a> =
  "Object.assign"

let dict = assign(dictA, dictB)

However, you mostly only need Js.Dict.t for interop with JS libraries.

Prefer using Maps where possible. Belt.Map.String for instance has a merge and a mergeMany method.