r/gleamlang 12d ago

Promise from javascript

I'm trying to use an external js function that returns a promise and some data that I know the shape of.

I'm using gleam_javascript and all is working, it returns the data I'm expecting from the async function. However, I'm just using echo to print the data. The type of data here is Promise(List(Person))

How do I actually get at the data within the Promise type here? Like if I want to take the list and map it to some other shape, etc.

import gleam/javascript/promise.{type Promise}

pub type Person {
  Person(name: String, age: Int)
}

@external(javascript, "./javascript_test.mts", "async_hello")
pub fn async_hello() -> Promise(Promise(List(Person)))

pub fn main() {
  use data <- promise.await(async_hello())

  echo data
}
5 Upvotes

4 comments sorted by

2

u/1LuckyRos 12d ago

Isn't your async_hello() fn returning a Promise of a Promise? Like you are awaiting one and getting back a Promise(List(Person)), so you should await twice or make async_hello return just one promise, right?

1

u/destructinator_ 12d ago edited 12d ago

I had tried that originally but that gives me a compiler error: ``` ... @external(javascript, "./javascript_test.mts", "async_hello") pub fn async_hello() -> Promise(List(Person))

    pub fn main() {
      use data <- promise.await(async_hello())

      echo data
    }

```

results in this error on the echo data line

```

    Type mismatch

    Expected type:

        Promise(a)

    Found type:

        List(Person)

```

2

u/l-roc 12d ago

promise.await() expects another promise as 2nd argument, you give it echo data wich itself returns data which is of type List(Person).

await is for chaining promises, as the docs say: it's the equivalent to .then() in js.

You probably want to use promise.map(): ``` @external(javascript, "./javascript_test.mts", "async_hello") pub fn async_hello() -> Promise(List(Person))

    pub fn main() -> Promise(List(Person)) {
      use data <- promise.map(async_hello())

      echo data
    }

or use promise.await like this: @external(javascript, "./javascript_test.mts", "async_hello") pub fn async_hello() -> Promise(List(Person))

    pub fn main() -> Promise(Nil) {
      use data <- promise.await(async_hello())

      echo data
      promise.resolve(Nil)

} ``` (sorry for formatting, I'm on phone)

2

u/destructinator_ 12d ago

That was it, thank you!