Fork me on GitHub
#clojurescript
<
2021-10-02
>
Tom H.06:10:32

Hey folks, I’m trying to write a macro that wraps secretary’s defroute and adds a check to the auto-generated URI function, here’s what I’ve got:

(defmacro safe-defroute2
  [name & body]
  `(do (secretary.core/defroute ~name ~@body)
       (alter-var-root
         (var ~name)
         (fn [f#]
           (fn [params#]
             (when (every? identity (vals params#))
               (f# params#)))))))

Tom H.06:10:17

But I see now that alter-var-root is clojure only, any ideas how I might do something similar in cljs?

thheller06:10:56

create an extra secondary name for the defroute and create a defn that does the checks and that calls the defroute?

thheller06:10:29

so you end up with (defroute foo* ...) and (defn foo [params] (check params) (foo* params))

Tom H.06:10:43

worked perfectly, thanks!

thheller06:10:46

alter-var-root is pretty much always a bad idea IMHO

Tom H.06:10:52

Ah yeah I see what you mean

Tom H.06:10:10

I’ll give that a go thanks!

Chris McCormick08:10:09

Is it possible to put a definition like "@keyv/sqlite" "^2.0.2" into :npm-deps or does the key have to be a keyword?

thheller08:10:41

strings are fine as keys. I'd even argue they should never be keywords

👍 1
Black10:10:06

Hi, I am using reagent (with re-frame), and I have task for adding some attributes to elements, so E2E tests can easily query elements on page. Is there an easy way to add some attribute resolver, so I dont have to call some function in every single element? I've looked into reagent compiler but I guess my thinking about problem is wrong. I would imagine that I can output some element like [:div {:test-anchor "x"}] and for production, html output is single div without any special attribute, but for testing environment there is some test attribute like data-test "x" . Only solution I am able to think about is just wrap all elements into some component handling this function, is my thinking wrong?

p-himik10:10:47

Assign clear identifiers to all the things you need to identify - even in production. You might think that there's little sense in it, but it is immensely useful with app metrics solutions that track what users do. E.g. Rollbar will clearly tell you what buttons were pressed and what inputs were changed right before some error on the page.

👍 1
borkdude13:10:26

Promise.resolve flattens promises when the value resolved is another promise. But in #nbb the result of an evaluation can be a promise which I don't want to resolve. How can I create a promise that resolves to another promise object, not to the result of that promise?

Karol Wójcik13:10:06

Have never seen anyone wanted to do it. Could you please elaborate why?

Karol Wójcik13:10:06

If you could also provide a snippet

borkdude13:10:18

I explained why. If someone evaluates 1 the result should be a promise that resolves to 1. If someone evaluates (js/Promise.resolve 1) the result should be a promise that resolves to a promise, not to 1 . See #nbb for more context.

borkdude13:10:16

The reason I'm wrapping "normal" values in promises is that some evaluations are expected to return promises (the namespace handling): so all results should be promises to normalize the API. But sometimes the evaluation should really be a promise within a promise since what the user was evaluating was a promise.

Karol Wójcik13:10:18

Thanks. This totally makes sense. Let me think for a few minutes

Karol Wójcik13:10:02

Probably the easiest way would be to create a Thenable alike type.

Karol Wójcik13:10:56

That way it would be easier to differentiate the Promise and your custom type. Actually not even Thenable since resolve will unwrap the value as well.

Karol Wójcik13:10:42

I don't know though if you have a control of calling the .then method in the eval context

Karol Wójcik13:10:55

If yes then this is one of the possible solutions

borkdude13:10:22

If JS doesn't support this then I should just switch to callbacks

borkdude13:10:09

or the API should always wrap evaluation results in an object

borkdude13:10:52

which kinda sucks

Karol Wójcik13:10:59

Who is wrapping namespace handling in promise?

Karol Wójcik13:10:35

Can you wrap it in fake Promise?

borkdude13:10:45

That would be similar to wrapping it in my own object stuff

Karol Wójcik13:10:12

Nested promises always flattens in JS

borkdude13:10:40

ok, then the options are: • callback based API • wrap eval result in object

Karol Wójcik13:10:22

Does namespace handling has to be done asynchronously?

borkdude13:10:10

this has to do with Ecmascript import being async / promise based

borkdude13:10:47

I guess I can just wrap the value

borkdude13:10:49

and be done with it

Karol Wójcik13:10:59

Hmm. But the imports are only async in the situations like x = import("something") 😮

Karol Wójcik13:10:38

The import sth from "something" is not async AFAIK. What is the reason you prefer async import?

borkdude13:10:52

this is a different discussion, I have already spent many hours discussing this with many people. let's take this as an assumption for now. the reason is that nbb uses dynamic import.

Karol Wójcik13:10:00

Maybe I'm asking just a stupid questions 😂

Karol Wójcik13:10:29

Sure. Try wrapping the value. Seems like the easiest thing you can do

borkdude13:10:02

Right. There seems to be no other way

borkdude13:10:05

or callbacks

Karol Wójcik13:10:10

Or callbacks, which are a little bit faster than Promise, but in CLJS it will be full PITA

didibus01:10:39

Not super familiar, but shouldn't it be that nbb uses .then to display the result of evaluation, instead of wrapping a promise over a promise?

didibus01:10:25

Hum, nope same issue. Ya seems you can't get around wrapping it somehow.