Fork me on GitHub
#clojurescript
<
2019-09-03
>
Aklscc05:09:25

What't the solution to use async and await in clojurescript?

thumbnail05:09:34

Afaik it’s not used, as other concurrency mechanisms are present. I do recall this tho; https://mobile.twitter.com/roman01la/status/1155602189311717377

Vesa Norilo06:09:43

I don't see how async and await are semantically meaningful for Clojure. They are kind of a kludge due to JS not having macros 😛

Vesa Norilo06:09:43

If you like, you could write an async/await let macro that binds a promise result to a variable and wraps the body in a then, wouldn't be surprised if someone had written one.

Vesa Norilo06:09:11

Alternatively, promise sugar could be added to a threading macro like ->

Vesa Norilo07:09:19

For the kicks I wrote a small toy implementation

; macro
(defmacro async-let 
  [bindings & body]
  (let [form (bindings 0) 
        async (bindings 1)]
    `(.then ~async (fn [~form] ~@body))))

; usage
(async-let [response (js/fetch "index.html")]
	(async-let [txt (.text response)]
		(println txt)))

Vesa Norilo07:09:54

it doesn't handle errors or more than just one binding

henrik07:09:59

I don’t get the point of async/await. Why is it a good idea to decide that the function is async upon declaring it, and not leave this detail to the caller?

henrik07:09:07

Anyway, there’s also https://funcool.github.io/promesa/latest/, which utilizes JS promises, I believe.

potetm11:09:44

> I don’t see how async and await are semantically meaningful for Clojure. > I don’t get the point of async/await. Ya’ll. srsly?

potetm11:09:05

core.async is a user-space impl of async/await

potetm11:09:16

@ULZE0PA2K The answer to your question is to use core.async. It provides roughly the same semantics as async/`await`.

potetm11:09:24

> They are kind of a kludge due to JS not having macros In a lot of (but not all) ways, core.async would be better were it tightly integrated w/ the compiler. There have been a number of compiler-level bugs that had to get rooted out of core.async. > Why is it a good idea to decide that the function is async upon declaring it, and not leave this detail to the caller? This is literally what go blocks do in core.async. If you want to know why that’s useful, go watch Rich’s talk on it.

Aklscc11:09:09

@U07S8JGF7 Thank you, it looks like a good answer. I will learn about them.

👍 4
lepistane08:09:25

Hi guys i have a question about interop. I am not sure how to approach the spreading of props DrawerItems {...props} how do i translate this to cljs?

thheller08:09:55

that is basically just creating a flat copy of props

thheller08:09:34

which CLJS usually doesn't need because of immutable data

lepistane08:09:14

so if i wrote only DrawerItems it should work?

thheller08:09:38

I don't have enough context to answer. you'd still need to pass it props

thheller08:09:56

but given that this is likely a JS component you might need to convert and so on

lepistane09:09:34

oki so for the context i am trying to use https://reactnavigation.org/docs/en/3.x/drawer-navigator.html i am creating drawer-navigator component in my re-natal app. it works but it uses the default drawer. I'd like to customize the drawer so i am translating this example https://medium.com/ltunes/how-to-do-hamburger-menu-in-react-native-application-200d92825988 to cljs. Sorry if this is stupid question but how do i pass props to js component? Do i just aset them?

thheller09:09:51

you pass props like you always do. so in reagent [:> DrawerItems {:the "props"}]

thheller09:09:10

or [:> DrawerItems props] if you already have a props map. that would match the {...props}

lepistane09:09:20

[drawer-items (clj->js props)] solved it thank you!

ag22:09:53

has anyone used material-ui with Clojurescript? I am unable to reproduce the following example from the official docs https://github.com/mui-org/material-ui/blob/master/docs/src/pages/components/dialogs/ResponsiveDialog.js#L13 and I can’t find Clojurescript examples where they use useTheme. When I do js/MaterialUIStyles.useTheme it returns a function, but executing that function causing

Uncaught Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component
any clues?

nenadalm16:09:33

I am using material-ui with reagent without issues. You can't use hooks inside reagent components: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md#hooks material-ui have also some higher order components - probably from historic reasons that you can use. As for the theme, here is sort of copy pasted code from one of the apps I am working on:

;; materia-ui.core (later aliased as `ui`)
;; ns contains react components after `reagent.core/adapt-react-class`

(def ^:private create-mui-theme* (goog.object/getValueByKeys js/window "MaterialUiStyles" "createMuiTheme"))

(defn create-mui-theme [theme]
  (create-mui-theme* theme))

;; app.core

(def ^:private theme
  (ui/create-mui-theme
   #js {:palette #js {:primary #js {:main "red"}}}))

(defn app []
  [ui/ThemeProvider {:theme theme}
   [current-page]])

ag17:09:19

Yeah, I didn’t see that doc until someone pointed at it. Thanks for the snippet, I’m gonna try it.

ag23:09:04

hmm. there’s something entirely else I guess, even this simple example doesn’t work:

(defn dialog []
  (let [[count set-count] (js/React.useState 0)]
    [:div
     [:strong "<-state Hook:"]
     " "
     [:button {:on-click #(set-count (inc count))}
      count]]))

dpsutton23:09:25

I don’t believe that react hooks can be used from reagent since reagent eventually ends up as react classes rather than functional components. Can be confusing because basically reagent gave functional components years before react had them

ag23:09:31

even if you use js/ReactDOM.render instead of reagent/render ?