0

I am trying to go over a list of items, cache the URL and then update the URL in the list before drawing it.

However I don't seems to be able to do so.

Any idea?

external cache: option(string) => Js.Promise.t({. "uri": string, "filePath": string }) = "get";

let items = result##data##data->Option.getWithDefault([||]);
let cachedUri = items
   ->Belt.Array.map(
         item =>
           cache(item##hosted_video_url)
           ->FutureJs.fromPromise(Js.String.make)
           ->Future.flatMapOk(cachedObj => (
             {. "hosted_video_url": cachedObj##uri }
           )
   ))
   ->Belt.Array.toList
   ->Future.all;
Natim
  • 17,274
  • 23
  • 92
  • 150
  • Where does `Future` and `FutureJs` come from? These don''t ship out-of-the-box with BuckleScript. Either way, the thing about futures and promises is that they represent future values. You can't just take it out since it might not be there yet. You have to wait for it, which means to continue the computation within the context of the future. There might be a `Future.all` function which lets you conveniently wait for all futures in a list, otherwise dealing with a list of future's ins't easy. – glennsl Sep 30 '19 at 16:00
  • They come from https://www.npmjs.com/package/reason-future – Natim Sep 30 '19 at 16:02
  • That does indeed have [an `all` function](https://github.com/RationalJS/future/blob/master/src/Future.re#L52-L60), so you can just use that then. – glennsl Sep 30 '19 at 16:04

1 Answers1

1

The idea is that you cannot exit a future, so you need to update the state inside the future thing rather than trying to get an equivalent of an asyncio.gather or something similar.

I changed:

setVerticalData(_ => {items-> Js.Array2.sortInPlaceWith((a, b) => {...})});

with

items
  ->List.fromArray;
  ->List.map(item =>
      cache(item##hosted_video_url)
        ->FutureJs.fromPromise(Js.String.make)
   )
   ->Future.all
   ->Future.map(cachedList => {
        setVerticalData(_ => {items: cachedList})
   })

Natim
  • 17,274
  • 23
  • 92
  • 150