Fork me on GitHub
#clojurescript
<
2022-09-09
>
Rambabu Patina05:09:14

Hi, I am trying to implement promises using promesa. My requirement is to call the method which returns promise on button click event, but getting some errors (i.e 'Invalid expression [object Promise]'). The button onclick code is

(button/ui-button
            {:appearance "primary"
             :isDisabled (not enabled?)
             :onClick
               #(comp/transact!
                   this
                   [(save-config!)
                    (p/let [(send-event! :settings {:p1 "test"})])
                    (close-dialog!)]
                   {:optimistic? false})}
            (tr "Save"))
The method is
(defn send-event! [settings]
          (p/promise
           (js/console.log
            {:message "Settings data: "
             :state settings})
           (helper/sendEvent
            constants/key
            constants/event
            (clj->js settings))))
So on button click event the promise needs to be resolved then close the window. Please suggest what I am missing. Your help is greatly appreciated. Thanks

Lone Ranger10:09:27

also I'm not super familiar with promesa but I'm thinking if it's anything like setTimeout or setInterval or a normal javascript promise, you should be wrapping a function in there

Lone Ranger10:09:13

Something like,

(defn send-event! [settings]
          (p/promise
          (fn [resolve reject]
           (js/console.log
            {:message "Settings data: "
             :state settings})
           (helper/sendEvent
            constants/key
            constants/event
            (clj->js settings)))))

skylize22:09:01

@U3BALC2HH No. p/promise is equivalent to js/Promise.resolve

skylize23:09:21

@U0340E8J196 you are passing 2 arguments to p/promise. The optional second argument is supposed to be an Executor, which would be in charge of managing queuing or concurrency of tasks handed to it. You need to pass only 1 value, so wrap everything up in`(do ...)`. It's very unclear whether this is helpful for your goal, though. I see 3 possibilities here: • helper/sendEvent returns immediately - Do you really even need a promise in this case? You can just return the value. • helper/sendEvent returns a promise You don't need to wrap it up again, just return the result, which is a promise. • helper/sendEvent does asynchronous work that you are trying to wait for p/promiseis not going to work because it resolves synchronously. In the last case, you will need something else. Probably p/create and passing a resolve function into helper/sendEvent as callback. My guess is you would rather move that into helper/SendEvent.

skylize23:09:12

So you would end up with something like

(defn sendEvent [key event settings]
 ;; return unresolved promise
 (p/create [resolve]
  ;; use resolve as callback when done 
  (handle-send-event key event settings resolve)))

---

(defn send-event! [settings]
 ;; now this already returns a promise
 (helper/sendEvent constants/key
                   constants/event
                   (clj->js settings)

Rambabu Patina10:09:20

Thanks @U90R0EPHA for detailed explanation! I will try the callback appraoch which seems suitable for my scenario.

agh2o18:09:20

Hi, I'm trying to register a handler for browser event of "POINTERUP" using google closure in a re-frame application. This is what I did, inorder to have the send-selection-event handler called upon a pointerup in any div.

; requiring [goog.events :as gevents] & [goog.dom :as dom] 
 (gevents/listen (dom/getElement "div") "POINTERUP" send-selection-event)
I have two questions, the first is if that is the right approach? the second is where should I put this event registering, because so far its not working very well. I'd also be grateful for a good place to read up on such things. (and in case the bigger picture is important: my goal is to have a re-frame event called upon a selection with the selected text passing as a parameter). thank you in advance

Lone Ranger19:09:54

Typically speaking you want to register an event handler in re-frame application as a declarative event handler on the component options map itself, :on-click etc. Re-frame components are just reagent components under the hood, so check out https://reagent-project.github.io/ for some examples. Now, if the declarative approach doesn't work for you -- and sometimes it doesn't -- then you're going to need to use what they call a "form-3" component. If you do not use a form-3 component, then the underlying React engine will just revert any changes you make that don't match the declarative implications of the reagent component (because React always tries to make the DOM match the data). However, using a "form-3" component gives you an escape hatch to apply things like your gvents/listen code.

Lone Ranger19:09:58

Eric Normand has some excellent work in this area. https://ericnormand.me/guide/reagent (note that what you are asking is actually a reagent question, not a re-frame question per se).

😃 1
JohnJ21:09:57

What options/libraries are available if I want to do SSR (clojure jvm) and hydrated on the browser with cljs? (assuming react)

rickheere01:09:51

https://github.com/tonsky/rum or if you search for reagent server side rendering there are some guide as well.

👌 1