Fork me on GitHub
#clojurescript
<
2021-12-09
>
Scott G04:12:56

How do I use JavaScript interop for triggering a Firestore cloud function when a new document is created? The following link has an example of what I'm trying to accomplish in ClojureScript. I need some assistance on getting the anonymous function with the two parameters snap and context to be called. https://firebase.google.com/docs/functions/firestore-events#event_triggers

Scott G04:12:23

This is a small snippet of what I've been trying. The issue I'm getting is that the anonymous function or the workflow function are never getting called.

(-> 
   (.document functions/firestore "users/{userId}/blog/{blogId}")
   .onCreate
   (fn [snap context]
(workflow snap context)
))

thheller06:12:38

looks to me like you are just missing a pair of parens?

(-> (.document functions/firestore "users/{userId}/blog/{blogId}")
    (.onCreate
      (fn [snap context]
        (workflow snap context)
        ))

Scott G17:12:21

Thanks. Yeah, had missed the extra parens when typing on my phone. Also tried the dot macro outlined at https://medium.com/multis/serverless-email-notifications-with-google-cloud-functions-and-clojurescript-fc58dfea067, but log statements inside the workflow fn aren't being called in either approach. I ended up replacing the create trigger via promises in a different spot on the code, which resolved the issue. Wonder if it had something to do with the Firebase emulator or dep version.

grav11:12:34

Looking quickly though the awesome cljs-math, there are a few functions that are simply wrapping the JS-version: https://github.com/quoll/cljs-math/blob/main/src/cljs/math.cljc#L111 I wonder if it wouldn't be more performant to do:

(def cos js/Math.cos)
vs
(defn cos [v] (js/Math.cos v))

grav11:12:09

At least it seems to make a difference in the advanced output of the compiler:

math.cos = (function math$cos(a){
return Math.cos(a);
});
math.sin = Math.sin;

grav11:12:41

But maybe the extra function call is optimized away by the js runtime?

Léo J11:12:39

Is there a good benchmarking tool in the cljs environment?

thheller17:12:54

most likely the defn variant is more performant

thheller17:12:21

given that the actual use likely generates different code

thheller17:12:56

ie. if the compiler knows it calls a fn it can invoke directly. otherwise it'll do the ifn indirection

👍 1
dnolen14:12:28

@grav it probably won't make any difference, this is definitely in the class of things that JS VMs will optimize

👍 1
1
Noah Bogart15:12:55

if I have a resources/public/index.html file that servers as my base for a reagent SPA, what’s the best way to get a CSRF token into the html? I understand how to do it if I generate it with hiccup directly so is that the best option here?

p-himik15:12:05

Any sort of templating, even regular replace will work if you have full control over index.html.

Noah Bogart15:12:15

maybe I should rephrase then: I’ve never worked with clojure/script templating before, so do you have any suggestions on which to use?

p-himik15:12:18

If it's just for CSRF token, then templating is an overkill - just use some sentinel value in index.html and use regular string replacement to replace it with the token. If you need something more than just a single token, selmer is a good choice.

👍 1
Noah Bogart15:12:27

a sentinel value is a smart idea, thanks. don’t think i need much more than that at the moment

👍 1
xavi17:12:20

Why does this work...?

(concat (clj->js [1 2]) (clj->js [3 4]))
; => (1 2 3 4)

p-himik17:12:18

Because you can call seq on JS arrays, which concat does behind the scenes. Also, just in case - note that (clj->js [1 2]) can be written simply as #js [1 2].

👁️ 1
xavi17:12:05

But this (that concat works with JavaScript arrays too) is undocumented behavior, right? I guess it's better I don't rely on this?

xavi17:12:52

The source of my doubt is that I was working with JavaScript Promise.all() and using js->clj and clj->js but now I realized that it seems to work even without those explicit conversions. For example, it seems Promise.all() works even when passed a ClojureScript list. I see Promise.all() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all. Do ClojureScript lists implement the JavaScript iterable protocol?

lilactown18:12:10

yes, clojurescript data structures are iterable

p-himik18:12:47

Also, your doubt is caused by an observation of the behavior in a "different direction" - using CLJS data structures with JS functions. While your initial question is about the reverse - using JS data structures in CLJS functions. And in general, given that seq works on JS arrays, I think it's safe to expect that seq-processing functions to also work in JS arrays, and for that behavior to remain there.

lilactown18:12:51

it's not documented well, but it is expected and changing it would be a breaking change, which generally doesn't happen

xavi20:12:36

Yes, @U2FRKM4TW , i understand my original question was about using JS structures with ClojureScript functions (`concat`), and then I asked about using ClojureScript structures with JavaScript functions (`Promise.all()`). Sorry for the confusion. @U4YGF4NGM Which one is not well documented? Using JS structures with CLJS functions, or using CLJS structures with JS functions? or both?

lilactown21:12:18

it's not obvious from any docs that arrays are seqable, or that vectors are iterable. but they are! and should continue to be

xavi21:12:47

Ok, I wanted to be sure that I was not missing any docs where this was mentioned. Thanks much both for your help!