Fork me on GitHub
#re-frame
<
2020-05-29
>
David Pham04:05:24

What if you make the GMAP atom outside of the component? Or create an fx for it?

Harish Tella04:05:38

I was thinking of this ideo too. I could store the Google maps object in the reframe-db when the component initializes. And when the time comes to call a function on this object, I could call a re-frame effect that essentially grabs the object from the reframe-db and calls the function on it. The only thing that stopped me was that it seemed not re-framey. It seemed like I was mutating this component through a back-door kind of approach, and the proper front-door approach was through the component’s props.

David Pham12:05:15

Fx are for side effects so kind of okay right?

Harish Tella14:05:49

True, but the docs, https://github.com/day8/re-frame/blob/master/docs/Effects.md, give examples of calling methods on databases or calling browser APIs, not calling a functions on some js-object within a reagent component. But in the end this could be the best approach.

Spaceman20:05:13

is it possible to dispatch multiple events when using reg-event-fx? like so:

{:dispatch [:event-foo p1 p2 :event-bar p3 p4}

Spaceman20:05:51

how does the order in which the events are dispatched work?

Spaceman20:05:27

is the order undefined or does the order depend on the order of events listed?

ggiraldez20:05:55

I think the remark on that page is outdated. AFAIK the order is undefined.

ggiraldez20:05:26

So if you need strict sequentiality you're better off dispatching the second event at the end of the first handler.

ggiraldez20:05:53

See @U0JEFEZH6 answer on the channel... in the source code, the note on the order was removed

Spaceman21:05:21

@U06B3TL74 I'm trying to set a Stripe token like so in an event-fx:

(.then (.createToken stripe card-element)
                 (fn [result]
                   (prn "result is" result)))
But I'm getting the error:
router.cljc:204 Uncaught Error: [object Promise] is not ISeqable
    at Object.cljs$core$seq [as seq] (core.cljs:1226)
    at re_frame$fx$do_fx_after (fx.cljc:74)
    at Object.re_frame$interceptor$invoke_interceptor_fn [as invoke_interceptor_fn] (interceptor.cljc:71)
    at Object.re_frame$interceptor$invoke_interceptors [as invoke_interceptors] (interceptor.cljc:109)
    at Object.re_frame$interceptor$execute [as execute] (interceptor.cljc:204)
    at Object.re_frame$events$handle [as handle] (events.cljc:65)
    at Object.eval [as re_frame$router$IEventQueue$_process_1st_event_in_queue$arity$1] (router.cljc:179)
    at Object.eval [as re_frame$router$IEventQueue$_run_queue$arity$1] (router.cljc:198)
    at eval (router.cljc:146)
    at Object.eval [as re_frame$router$IEventQueue$_fsm_trigger$arity$3] (router.cljc:169)
why might this be?

Spaceman21:05:08

where

(let [stripe (js/Stripe. "foobar")
      elements (.elements stripe)
      card-element (.create elements "card" some-style)] ...)

ggiraldez21:05:53

Looks like you're trying to return a promise from the event handler. At least that's what I think the error means.

ggiraldez21:05:29

On the one hand this is not allowed as you should return a map of effects. And on the other hand, you should keep your event handlers side-effect free and use effects (registered with reg-fx) instead.

ggiraldez21:05:26

I'm not familiar with the Stripe API, but I assume .createToken there has a side effect. You should register that functionality in a re-frame effect which can be triggered from the event handler.

Spaceman21:05:44

yeah, how would I return a map if I'm using (.then ..) ? I feel that I would need to make it impure and use (dispatch ...) instead inside of the (.then ...)?

Spaceman21:05:36

Ultimately, I want to return a map {:db (assoc db :stripe-token (.-token result))}

ggiraldez21:05:33

Right. But obtaining that token is an effect.

ggiraldez21:05:39

Try something like this:

ggiraldez21:05:25

(reg-fx ::create-stripe-token
  (fn [params]
    (.then (.createToken stripe params)
      (fn [result] (dispatch [::token-created result])))))

ggiraldez21:05:04

Then you need a handler to save the token, ::token-created which will just to the assoc you mention

Spaceman21:05:06

Is there no way to keep it pure?

ggiraldez21:05:40

And you invoke the effect by returning {::create-strip-token params} from the original handler

Spaceman21:05:47

I mean, do I have to call (dispatch ...) this way?

ggiraldez21:05:50

The effect will not be pure of course

ggiraldez21:05:11

This is an effect, not an event handler

ggiraldez21:05:26

ie. reg-fx vs reg-event-fx

ggiraldez21:05:29

Event handlers you can keep pure. Effects are the place where you make your side effects.

Spaceman20:05:36

or is it better to do them sequentially?

Spaceman20:05:25

But what if all p1, p2, p3, p4 are scoped in the current handler, then do I need to first call:

{:dispatch [:event-foo p1 p2 p3 p4]}
and then in :event-foo call:
{:dispatch [:event-bar p3 p4}
?

Spaceman20:05:06

I'm attempting to keep the functions pure

Spaceman22:05:10

what does this error mean?:

Uncaught TypeError: lastCallbackNode is not a function
    at flushFirstCallback (scheduler.development.js:108)
    at flushImmediateWork (scheduler.development.js:170)
    at exports.unstable_runWithPriority (scheduler.development.js:262)
    at runWithPriority$2 (react-dom.development.js:11306)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11350)
    at flushSyncCallbackQueue (react-dom.development.js:11339)
    at scheduleWork (react-dom.development.js:21432)
    at Object.enqueueForceUpdate (react-dom.development.js:13146)
    at cmp.Component.forceUpdate (react.development.js:354)
    at Object.reagent$impl$batching$run_queue [as run_queue] (batching.cljs:38)