Fork me on GitHub
#clojurescript
<
2019-01-17
>
pez12:01:26

Anyone knows how, using bidi clientside, I can let a pattern ”escape” the router and thus my SPA? I want /api to result in a request for the web server and /<anything else> to be routed inside my SPA. My google fu only digs up an old blogpost of my own writing, which does not answer this question…

kwladyka13:01:19

(ns form-validator-demo.routes
  (:require [re-frame.core :as re-frame]
            [bidi.bidi :as bidi]
            [accountant.core :as accountant]
            [taoensso.timbre :as l]))

(def route ["/" {"" :main
                 "log-in" :log-in
                 "log-out" :log-out
                 "sign-up" :sign-up
                 "forgotten-password" :forgotten-password}])

(defn path->request [path]
  (bidi/match-route route path))

(defn handler->path [handler]
  (bidi/path-for route handler))

(defn navigate! [path]
  (accountant/navigate! path))

(defn hook-browser-navigation! []
  (accountant/configure-navigation! {:nav-handler (fn [path]
                                                    (re-frame/dispatch [:load-path path]))
                                     :path-exists? (fn [path]
                                                     (l/info "exists?" path (bidi/match-route route path) (boolean (bidi/match-route route path)))
                                                     (boolean (bidi/match-route route path)))})
  (accountant/dispatch-current!))
and do something like that

kwladyka13:01:05

notice :path-exists?

pez13:01:29

@kwladyka: thanks, I am using Accountant as it happens. I'll fiddle some with my path-exists? handler and see what it gets me.

WhoNeedszZz19:01:08

I've found kibu/pushy to be much simpler to use

borkdude13:01:38

what does accountant add on top of bidi / secretary?

pez13:01:50

… seems my problem is I have a catch-all route.

kwladyka13:01:33

you can check if it is :status 404

kwladyka13:01:53

I guess it is you :catch-all

kwladyka13:01:09

Or find different way to check it

pez13:01:12

Part of my problem is that we have a simpler syntax for the bidi table, that we transform. I am trying to figure out what our syntax allows.

kwladyka13:01:51

Wrapper on simple bidi syntax sounds like an issue 😉

pez13:01:09

Not my idea! 😃

kwladyka13:01:22

I believe! 🙂

pez13:01:08

I think the bidi syntax is simple enough. But people borked it all the time, and someone decided to wrap it.

kwladyka13:01:06

For me bidi syntax is perfect. At least I don’t have better idea how it could be done better

pez13:01:18

reitit maybe

pez13:01:30

Yeah, metosin's router.

kwladyka13:01:07

no idea what does it mean 😛

kwladyka13:01:15

nevermind 😉

kwladyka13:01:08

What pros vs bidi? I don’t know this library

pez13:01:48

I am not very familiar with it. I think it depends on the use case. Fore huge routing tables, it offers speed, even speed matching Pedestal's. And also, from what I have seen, it's syntax would trip my colleagues a bit less. 😃

kwladyka13:01:18

thanks for showing it

👍 5
pez13:01:40

@borkdude accountant is a html5 history library

borkdude13:01:23

ah, it seems we have implemented that part ourselves in adjunction to secretary

pez13:01:16

@borkdude before going with bidi, I'd suggest checking out reitit. (iirc they have bundled a html5 handler with it).

borkdude13:01:45

we’re already using secretary, no reason to change right now.

pez13:01:26

Eventually you will, I am sure. Secretary is old hat. 😃

borkdude13:01:28

but reitit sounds good yes. we’re using yada on the backend which is coupled to bidi.

WhoNeedszZz19:01:11

yada and bidi aren't coupled. They just suggest you use bidi as that is also their library and they know it will work as intended together. You're free to use any other library.

borkdude19:01:41

yes, dominicm already correct me

WhoNeedszZz19:01:02

Didn't see that yet, sorry

borkdude13:01:56

it’s old, but it works, we haven’t changed that code in a long while 😉

kwladyka13:01:36

@borkdude Do you use yada with redis DB sessions? Does yada work with peridot?

borkdude13:01:51

btw, secretary is now a clj-commons project. at least it’s in maintenance mode. https://github.com/clj-commons/secretary

kwladyka13:01:00

I mean how simple is add ring middlewares with yada?

dominicm13:01:00

@borkdude yada isn't coupled to bidi, but does provide convenient integrations with it.

👆 5
borkdude13:01:13

@kwladyka you can use ring stuff with yada, although we got rid of a lot of the ring stuff we had. see https://twitter.com/borkdude/status/857979807358910464

borkdude13:01:26

@dominicm I stand corrected

kwladyka13:01:57

good, I was trying yada a few days, but I had feeling it needs +1 year. Maybe I give up too fast. hard to say

borkdude13:01:28

it’s almost two years since I posted that tweet

kwladyka13:01:53

I was trying yada about 1 week ago 😉

borkdude13:01:34

@dominicm now that you say this, maybe we could use reitit with yada then. it also replaces Schema by spec for validation? then we could migrate that too. do you know any projects that did this?

WhoNeedszZz19:01:24

reitit and yada accomplish the same thing so you wouldn't use them together.

borkdude19:01:52

reitit is not a competitor for bidi, as in, routing?

WhoNeedszZz19:01:21

Reitit does more than routing

WhoNeedszZz19:01:03

They have a separate documentation link on there as well

borkdude19:01:25

I read that, but from that I understood it’s a routing lib. not clear to me that you can’t plug it in like bidi in yada

WhoNeedszZz19:01:38

I do suggest you just use bidi since it is designed to work together

borkdude19:01:59

that’s what I meant with “coupled” kind of

borkdude19:01:36

I guess I need more zzz

😄 5
WhoNeedszZz19:01:41

It does do some things for you automatically by including it, if that's what you mean, sure.

WhoNeedszZz19:01:51

I just deployed a website with yada and bidi on the backend API and re-frame, bidi, and pushy on the front-end. Worked very well together

borkdude19:01:31

yeah, we already had the front-end before yada, but bidi would make sense when redesigning it

WhoNeedszZz19:01:05

yeah, that's the beauty of the front-end not being coupled with the back-end

borkdude13:01:02

@kwladyka if you have any questions, feel free to post in #yada.

kwladyka13:01:17

I have feeling doc could have 20% of the content with the same or higher value. Just I couldn’t achieve things. Like for example I didn’t want to throw exceptions to users face in web browser. How to turn off it? Somebody point me on #yada to place in the code, but there is no word about that in doc. In other words IMO the weakest point of yada is doc.

WhoNeedszZz19:01:41

I'm not even sure what you mean here. I don't have any errors being thrown to the user on my site...

kwladyka20:01:29

When I throw exception it is showed on web page

kwladyka20:01:38

there is no info in the doc how to turn it off

kwladyka20:01:43

unless I miss that

kwladyka20:01:00

AFAIK there is a way to turn it off, but it is not described in the doc

WhoNeedszZz20:01:00

Again, no idea what you mean specifically. Showing the actual code would be helpful...

kwladyka20:01:06

^for example, even with 404

kwladyka21:01:49

I don’t have code at that moment, because I switched for liberator for now

kwladyka21:01:19

But I will back to yada in the future for sure!

WhoNeedszZz03:01:38

Liberator is for creating ReSTful resources so it's not a replacement for yada. Liberator is used in conjunction with ring to provide the serving of the data. That's what yada does. You can use liberator with yada, but it does not replace it. The documentation for Liberator uses Compojure for the routing, but suggests bidi as an alternative, which is the recommendation with yada.

kwladyka08:01:57

I know. So how do you hide exception on web page when 404? I will give yada a second chance today probably 🙂

WhoNeedszZz08:01:53

I don't know the answer to that, but it could be a development mode only thing. Have you tried making a production build just to see if it does it there? For me it doesn't return a 404, but instead a 204.

kwladyka08:01:19

Hmm so you are saying with :adavanced compilation it could work differently? I have never seen such solution. But who knows. I didn’t try it.

kwladyka08:01:18

Anyway I will try yada again today with more experience after liberator and things around. It could help.

👍 5
kwladyka08:01:33

to see things differently

kwladyka13:01:52

I would love to use it, but today I don’t feel comfortable with it. Maybe I should try once again.

borkdude13:01:17

at least there are docs, although they’re not complete. when I did a comparison between Pedestal and yada, I found yada much more accessible doc-wise

WhoNeedszZz19:01:31

It is missing some things. I was told by Dominic that he just consults the tests for those pieces until they are fully documented.

borkdude13:01:29

maybe now it’s different, don’t know

kwladyka13:01:50

I have never used Pedestal. Only ring and liberator. I can’t compare this two.

borkdude13:01:29

@kwladyka as for the error handling code. I can post my code if you want to have a peek

borkdude13:01:03

I removed some specific things to our app, but this is the gist of it: https://gist.github.com/borkdude/441379ec59d8da7f72348453ee15f32a

borkdude13:01:04

in dev I throw exceptions at my face in the browser, but in prod I don’t (they’re logged to sentry)

kwladyka13:01:33

Do you use yada with graphql?

kwladyka13:01:54

I have concern about graphql auth and security

kwladyka13:01:01

with yada / liberator / ring

kwladyka13:01:07

trying to find the best solution

borkdude13:01:15

that’s an entirely different topic, but right now we don’t. I suggest talking in #yada, since this is going off topic now

kwladyka13:01:29

but probably auth has to be moved into graphql and there is really no library to support it

orestis14:01:00

My hacky macro to get translations hooked up in CLJS actually paid off. I’ve closed the circle and now can upload my .pot files to translation, and read back .po files (using pottery). Good stuff! :happy-dance:

orestis14:01:30

Yes, but only to parse .po files. I generate my own .pot files because I needed to do the pre-processing of messages on my own.

Karol Wójcik19:01:08

I’m trying to create a macro which is the combination of go and let. What is very bizzare is that every time I try to evaluate the macro I receive the information that var cljs.core/destructure is undeclared 😮 How to make it work? What I’m missing?

(ns some-example.macros.async
  (:refer-clojure :exclude [destructure])
  (:require
   [clojure.core.async]))

#?(:cljs
   (defmacro go-let
     [bindings & body]
     `(clojure.core.async/go (let* ~(cljs.core/destructure bindings) ~@body))))

Karol Wójcik19:01:37

Anyone know how to do it?

darwin22:01:59

anything you put into ~(...) must be valid clojure code, where did you require cljs.core namespace?

madstap16:01:37

Why are you using let* and destructure instead of just using let?

Karol Wójcik17:01:49

Because I would still to destructure bindings

Karol Wójcik17:01:13

Ok I got it. let will do it for me 😄 Thank you @U0J9LVB6G

Karol Wójcik17:01:22

You’re completely right 🙂

madstap17:01:45

Glad I could help 🙂

Karol Wójcik11:01:51

@U0J9LVB6G I’m still struggling with this one:

(ns some-example.macros.async
  (:require-macros
   [cljs.core])
  (:require
   [clojure.core.async]
   [cljs.core]))

(defmacro go-let
  [bindings & body]
  `(clojure.core.async/go
     (cljs.core/let ~bindings ~@body)))

Karol Wójcik11:01:43

It seems that the bindings are nil 😮 How come?

Karol Wójcik11:01:12

What is even more bizzare is that it works perfectly fine in plain clj.

(defmacro go-let
  [bindings & body]
  `(clojure.core.async/go
     (let ~bindings ~@body)))

(go-let [a 1]
        (println a))
Is it caused by the fact that I got it defined in cljc instead of .clj? @dnolen?

madstap12:01:36

It's considered rude to @ people that are not a part of the conversation at the moment.

madstap12:01:47

About your problem, you should just use let instead of cljs.core/let. That last version should work in a cljc file as well.

Karol Wójcik12:01:48

Well dnolen already was a part of the conversation since he was answering my question. Maybe not in that thread but definitely he was involved in helping me. If you feel that my behaviour is rude dnolen, please forgive me. I’m sorry if you feel offended.

Karol Wójcik12:01:47

@U0J9LVB6G I’m receiving the error:

[Figwheel:SEVERE] java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IObj
Could not Analyze   <cljs repl>   line:1  column:1

  clojure.lang.Keyword cannot be cast to clojure.lang.IObj

  1  (masync/go-let [a 1]
     ^---
  2                 (println "abc"))
(masync/go-let [a 1]
               (println "abc"))
after using the last snippet

Karol Wójcik12:01:25

Ok solved the issue 😄 I had to add macros from cljs.core and require the cljs.core 😄

Karol Wójcik12:01:22

Thank you @U0J9LVB6G for you patience and help!

🙂 5
lilactown20:01:07

how can I create a macro that attaches metadata to a var?

lilactown20:01:27

(defmacro defstart! [args & body]
  `(do
     (defn ~'-start! ~args
       ~@body)
     ;; check if we're in node; if not, don't create the reloadable start
     (when-not (cljs.core/exists? js/process)
       (defonce
         ~(with-meta 'start! {:export true :dev/after-load true})
         (hecate.loader/reloadable (var ~'-start!))))))
seems not to be working for me

dnolen20:01:50

there are no real vars

dnolen20:01:03

given that what are you trying to accomplish?

lilactown20:01:08

in our project, we have a lot of entry points into various parts of the app. each entry point has a bunch of boilerplate

lilactown20:01:16

e.g.:

(when-not (exists? js/process)
  (defonce ^{:export true :dev/after-load true} start! (reloadable (fn [dom-ref {:keys [config]}]
     (r/render [app config])))))

lilactown20:01:53

I'm trying to clean this up with a macro:

(defstart! [dom-ref {:keys [config]}]
  (r/render [app config]))

lilactown20:01:06

and it will expand to something close to the above

lilactown20:01:39

@dnolen does that make sense? possible? 😬

dnolen21:01:21

I see you just want to make a macro that expands to a def w/ metadata, that should work

lilactown21:01:00

but my code above for some reason is not exporting properly when I do a release

lilactown21:01:13

(defonce
         ~(with-meta 'start! {:export true :dev/after-load true})
         (hecate.loader/reloadable (var ~'-start!))

Roman Liutikov21:01:52

I've done this recently with vary-meta, it works

Roman Liutikov21:01:07

But in a macro

lilactown21:01:40

did the vary-meta execute at macro-time or at run-time?

lilactown21:01:58

cool I'll try that

Roman Liutikov21:01:00

Let me find it

dnolen21:01:47

I don't see anything obviously wrong at the moment, but can't look too closely right now

dnolen21:01:55

I would try something simpler - no defonce etc.

dnolen21:01:20

@kwcharllie379 you're not requiring the cljs.core macro ns so that won't work