Fork me on GitHub
#re-frame
<
2023-04-18
>
Ben Lieberman14:04:45

Is there something obviously wrong with this reg-cofx that I am missing? When I inject it into my app startup fx handler, it only ever breaks the app or shows [nil nil] for the position.

(reg-cofx
 :config/geolocation-enabled?
 (fn [coeffects]
   (.. js/window -navigator -geolocation
       (getCurrentPosition (fn [position] (let [lat (.. position -coords -latitude)
                                                lon (.. position -coords -longitude)]
                                            (-> coeffects 
                                                (assoc :current-lat lat)
                                                (assoc :current-lon lon))))))))

Ben Lieberman14:04:27

I suppose the app startup handler is being queued before the cofx handler?

lassemaatta14:04:54

that getCurrentPosition looks like an async API? at least according to https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition#return_value the return value is undefined

Ben Lieberman14:04:55

I can use console.log on it without awaiting it or using .then or any of that jazz but yeah it doesn't seem to return anything

Ben Lieberman14:04:06

the geolocation API also prompts the user to allow access, and so you have to click the little popup before it runs this code I'm guessing

Ben Lieberman14:04:52

I tried wrapping it in (.addEventListener js/window "DOMContentLoaded" (fn [] ...) to no avail

lassemaatta14:04:52

I think what you might want to do is a) create a reg-fx , which invokes that geolocation API and stores the result in a atom (and perhaps dispatches an event indicating that the data is available) and b) fetch the contents of that atom in your reg-cofx handler.

lassemaatta14:04:21

or alternatively: just dispatch an event in the callback function and include the location data in the event and then store it in the app-db as normal.

p-himik14:04:47

Yeah, you can't use async functions in co-effects. I would definitely go with the latter approach of dispatching 2 events - one to call the geolocation function and the other to store that data in app-db. It won't solve the timing issue though, so you gotta reshuffle your events in a way that makes it work even when getCurrentPosition takes a lot of time (I think it doesn't resolve the promise till the user confirms the request).

Ben Lieberman14:04:14

Sounds good, thanks for the help/suggestions @U0178V2SLAY @U2FRKM4TW