Accessing the Properties of a Record Wrapped in Aff in FFI

I have a record as seen below:

EdictRequest :: { build ∷ String , mediaErrors ∷ MediaErrors , osVersion ∷ String , playerIP ∷ Maybe String , playerLicense ∷ PlayerLicense , playerVersion ∷ String , quickBroadcast ∷ Boolean , rx ∷ Maybe Number , screenHeightPx ∷ Number , screenWidthPx ∷ Number , storageFree ∷ Maybe Number , storageTotal ∷ Maybe Number , tx ∷ Maybe Number }

that is wrapped in an Aff edictRequest ∷ Aff EdictRequest
I am passing it into javascript through a FFI with the following definition and implementation:

foreign import disectEdictReq ∷ EffectFn1 (Aff EdictRequest) Unit
runEffectFn1 disectEdictReq cfg.edictRequest # liftEffect

The definition and implementation is syntactically correct and compiles however the result is not what I expected. When i attempt to see the keys of the Object it returns [tags, _1, _2, _3] instead. Is there a way to forcibly unwrap an Aff? I understand that Aff is asynchronous however in this context it is being used in a synchronous manner. Any help will be appreciated.

In order to get the result of an Aff, you must use runAff or launchAff and provide a callbback, just like with Promises you must use .then.

You should probably make you function

EffectFn1 EdictRequest Unit

and then you can do

example :: Aff Unit
example = do
  edictReq <- myAffFunctionThatGetsAnEdictReq
  liftEffect $ runEffectFn1 disectEdictReq edictReq
1 Like

If you ever do need to work with an Aff over an FFI boundary, this module has been helpful to me in the past to convert between Aff and Promise, (since Promise is something you can work with in JS) though keeping the Aff on the PureScript side the way Nate showed is clearly the better option if possible.

Thanks. Your answer really helped me out. Im not the original author of the code and the author is no longer with the company. I was an emergency hire so while I am familiar with the code I dont really understand a lot of whats going on. Your code examples helped me to realize that I was performing the action in the wrong location.

Im going to include the solution for posterity

  acquireEdict ∷ Aff Edict
  acquireEdict = try edictRequest >>= \req →
    let cacheKey = ....
      { name: "the player instructions"
      , contentKey: Nothing
      , fileSizeInBytes: Nothing
      , cacheKey
      { strategy: FetchElseCache
      , virtURL: tmpCacheURL <> cacheKey
      , realURL: formEdictURL $
          (fromMaybe defaultEdictRequest (hush req)) { playerLicense = lic }
      , md5Checksum: Nothing
      ResponseFormat.json >>= case _ of
        Nothing →
          throwError (error "Acquire aborted because unable to obtain Edict")
        Just json → do
          liftEffect $ runEffectFn1 disectEdictReq (fromMaybe defaultEdictRequest (hush req))

Thanks again. I was really stuck on this

I will look into that. It seems very useful