Fork me on GitHub
#clojurescript
<
2019-11-25
>
orestis06:11:56

@gr.evocatus it’s certainly possible (see Machiatto for an approach) but IMO it’s not worth the trouble. We are migrating away from a JS/Node.js backend to a Clojure/JVM one, and both dev and ops are just so much better.

💯 2
👍 2
martinklepsch14:11:36

Is there some performance benefit to reusing a transit writer rather than creating it for every read operation? The API kind of suggests there is but the docs aren’t explicitly saying “For best performance reuse writer and reader instances.“…

p-himik14:11:36

I think if you're using the :json-verbose output, there's no difference. And if you're using :json output, reusing the same writer will result in proper caching.

martinklepsch16:11:55

Thanks that makes sense!

dpsutton14:11:40

if you're in a react based world there are ref functions. (i wish i could collapse the snippet here back into a link but alas)

parens 1
metehan14:11:07

thank you this is exactly what I was looking for

parens 1
yerba-mate 1
p-himik14:11:38

I'm not sure about using an atom there. How is it better than react/createRef?

roman01la14:11:09

@p-himik perhaps more idiomatic API in Clojure world

roman01la14:11:41

especially if you do run stuff on JVM as well

p-himik14:11:22

Maybe more idiomatic, yes. But how does using react/createRef prevent you from running stuff on JVM when you already use React?

roman01la14:11:17

you’d have to wrap react api usage into reader conditions, because it’s JS library

👍 1
p-himik15:11:27

I just noticed that I'm getting dangerous use of 'this' in static method hgs.platform.abc.core.NotePrinter with this code:

(defn NotePrinter []
  (this-as this
    (.call ABCMusicListener this)))

(set! (.. NotePrinter -prototype)
      (js/Object.create (.-prototype ABCMusicListener)))

(set! (.. NotePrinter -prototype -constructor)
      ABCMusicListener)

(set! (.. NotePrinter -prototype -enterNote)
      (fn [ctx]
        (js/console.log "NOTE" ctx)))
Am I doing something wrong here? Is there a better way to implement NotePrinter?

roman01la15:11:24

(defn NotePrinter
  "@this {NotePrinter}"
  []
  (this-as this
    (.call ABCMusicListener this)))

roman01la15:11:42

This is Closure Compiler complaining about referring to this within plain function, providing annotation in doc string will fix it, see https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#this-type

p-himik15:11:05

Will try, thanks!

thheller15:11:27

@p-himik (defn ^{:jsdoc ["@constructor"]} NotePrinter [] ...) would be the correct way to define a custom type. then it'll recognize the other prototype props properly as well

roman01la15:11:22

is it required to put annotation into jsdoc meta?

p-himik15:11:10

Both approaches seem to work. But I like the :jsdoc one a bit more because it doesn't require repeating the type's name.

thheller15:11:27

you can put it into the regular docs too but then it will appear as part of the regular docs 😛

grounded_sage16:11:04

Is there any examples online of using AWS Amplify Auth from Cljs?

grounded_sage16:11:57

I'm trying to translate this code and have no idea what is going on lol https://gist.github.com/groundedSAGE/995dc2e14845980fdc547c8ba510169c

em16:11:53

There's https://github.com/cjsauer/aws-amplify-cljs as an example but is slightly outdated. Honestly the best approach would just be to use native interop with the Amplify library. https://aws-amplify.github.io/docs/js/authentication One little thing to note is that amplify comes with wrappers for the popular frameworks like Vue and React; trying to use those through interop would be unnecessarily confusing. If you stick with the basic library calls on Auth the process should be straightforward and simple for most authentication needs.

👍 1
Ben Hammond16:11:46

I'm using https://github.com/tonsky/rum to interop with React, and I'd like to put in some https://reactjs.org/docs/error-boundaries.html it doesn't look like rum.core/build-class supports getDerivedStateFromError or componentDidCatch is there a standard way to do this? I suppose I could use

(gobj/set prototype "getDerivedStateFromError"
to manually poke handlers in

Ben Hammond16:11:36

oh, I just spotted

did-catch      (collect   :did-catch mixins)        ;; state error info -> state

Ben Hammond13:11:55

(let [err (atom nil)]
  (rum/defc error-boundary < {:did-catch
                              (fn [error info]
                                (reset! err info))}
    [& children]
    (if-let [rinfo @err]
      [:pre [:code (pr-str rinfo)]]
      children)))
seems to do what I want (mostly pinched from https://lilac.town/writing/modern-react-in-cljs-error-boundaries/)

Aleks Abla18:11:17

Hey all, hope the week has been off to a great start. I am trying to understand the ins and outs of ToDoMVC example with reagent. I am having trouble comprehending the logic behind inputting and storing 'todos' in the table. Why do we want to use LocalStore in this example? Is there a way to do it without local store? Thanks 🙂

lilactown18:11:29

part of the requirements for todomvc is that you persist the todos to local storage

jahson18:11:22

If you don't need the local storage, you could just remove the interceptor. https://github.com/day8/re-frame/blob/master/examples/todomvc/src/todomvc/events.cljs#L80

Aleks Abla19:11:31

oh that's awesome! thanks for the quick replies -- I won't be needing that functionality in my application, but it's a great thing to know!

ec19:11:58

hey, I am using re-frame template how do I make lein dev watch the index.css that I linked in resources/public/index.html file?

grounded_sage20:11:27

I'm trying to use cljs-time recursively check if things are within a certain date and then render them. But for some reason having the symbol of t there is throwing an error.

(within? (interval
          (plus (now) (weeks t))
          (plus (now) (weeks (inc t))))
    object-in-question)

grounded_sage20:11:51

This is the error message Uncaught Error: Assert failed: (<= (.getTime start) (.getTime end))

jahson20:11:18

You should probably check the actual value of start and end values of the interval https://github.com/andrewmcveigh/cljs-time/blob/master/src/cljs_time/core.cljs#L142

grounded_sage20:11:08

Seemed to work when I pre-compute the interval.

grounded_sage20:11:18

Must be something to do with within?

p-himik20:11:21

interval throws that error. within? is called after interval. It cannot be within?.

grounded_sage06:11:54

I pulled interval out of within and out it in a let binding ‘(let [my-interval (interval (now) (plus (now) (weeks t))])’ then it started working using ‘my-interval’ in ‘within?’. But calling that directly within ‘within?’ It broke ??

p-himik07:11:20

Before you had

(interval
          (plus (now) (weeks t))
          (plus (now) (weeks (inc t))))
Now you have
(interval (now) (plus (now) (weeks t)))
Notice the difference?

Aleks Abla21:11:15

another re-frame question -- I am trying to update the db based on changes happening in the :select multiple. I am able to log change of :select in console, but not sure how to access the values in select to update the db. code and image for reference below.

Aleks Abla21:11:49

ideally, after selecting one (or multiple) , we would call an event-handler function to assoc the change in db

p-himik21:11:50

@ablazevix Try Adding % in that logging statement.

Aleks Abla21:11:51

yep, I tried and got a large blurb back

Aleks Abla21:11:08

SyntheticEvent {dispatchConfig: {…}, targetInst: FiberNode, dispatchInstances: FiberNode, nativeEvent: Event, _dispatchListeners: ƒ, …} bubbles: (...) cancelable: (...) currentTarget: (...) defaultPrevented: (...) dispatchConfig: null eventPhase: (...) isDefaultPrevented: (...) isPropagationStopped: (...) isTrusted: (...) nativeEvent: (...) target: (...) timeStamp: (...) type: (...) _dispatchInstances: null _dispatchListeners: null _targetInst: null preventDefault: (...) stopPropagation: (...) get bubbles: ƒ () set bubbles: ƒ (val) get cancelable: ƒ () set cancelable: ƒ (val) get currentTarget: ƒ () set currentTarget: ƒ (val) get defaultPrevented: ƒ () set defaultPrevented: ƒ (val) get eventPhase: ƒ () set eventPhase: ƒ (val) get isDefaultPrevented: ƒ () set isDefaultPrevented: ƒ (val) get isPropagationStopped: ƒ () set isPropagationStopped: ƒ (val) get isTrusted: ƒ () set isTrusted: ƒ (val) get nativeEvent: ƒ () set nativeEvent: ƒ (val) get target: ƒ () set target: ƒ (val) get timeStamp: ƒ () set timeStamp: ƒ (val) get type: ƒ () set type: ƒ (val) get preventDefault: ƒ () set preventDefault: ƒ (val) get stopPropagation: ƒ () set stopPropagation: ƒ (val) proto__: Object

p-himik21:11:41

OK, try to access target. And it will probably have the value field.

Aleks Abla21:11:55

do you find yourself often looking up react solutions to solve reagent problems?

p-himik21:11:21

Of course! Because Reagent is but a wrapper on top of React.

p-himik21:11:13

In essence, it just allows you to write React applications by using ClojureScript and sticking with more or less idiomatic ClojureScript code.

Aleks Abla21:11:18

oh thats helpful! I'll try doing that too, but might need more react skills then

p-himik21:11:10

Just note that Reagent is lagging a bit. E.g. AFAIK there's no support for React hooks.

p-himik21:11:51

Also, given your last comment under the image, you probably want to set :on-change to something like #(dispatch [:headers-ev/select select-id (.. % -target -value)]) where :headers-ev/select is a re-frame event registered somewhere. I'm not sure whether (.. % -target -value) will work properly in production, where you'd use advanced optimizations. But that's a different question.

Aleks Abla21:11:46

yep, here's the solution for logging the change

Aleks Abla21:11:52

#(js/console.log (-> % .-target .-value))

p-himik21:11:41

Yep. (.. % -target -value) is a shorter form of (-> % .-target .-value).

p-himik21:11:17

To try things out to see how they turn into JS you can use http://app.klipse.tech/

Aleks Abla21:11:20

that's awesome man.. the way you can interact with objects..

p-himik21:11:57

You may like https://github.com/binaryage/cljs-oops It allows using things like (oget x :?a.?b.?c) where none of the fields may exist - it will not throw an error, it will return just nil. Although be sure to use it primarily for data (i.e. JSON). There are various concerns when using it with proper objects due to how stuff gets compiled.

p-himik21:11:51

Also, since it's Clojure where we can use macros, (oget x :?a.?b.?c) is actually turned into a minimal JavaScript, without any overhead whatsoever.

Aleks Abla22:11:22

haha, definitely on the map, though still some time before I get comfortable with those. 🙂

kenny21:11:22

I have some cljc that uses alias which does not work in cljs because there is no alias function. What do people use in place of Clojure's alias function?

p-himik21:11:49

I assume the absence of the function has something to do with how CLJS is compiled. I've never used alias myself. Out of interest - how do you use it?

kenny21:11:34

Top level of the namespace. (alias 'core 'myapp.core)

p-himik21:11:11

I probably misunderstand something. How is it different from (require '[myapp.core :as core])?

p-himik21:11:37

Ah, so it doesn't require the existence of the referenced namespace, which is useful for keywords. I see.

thheller21:11:30

there is no replacement for alias currently. only option is to use the full namespace

kenny21:11:05

Oof. A bit surprised given alias is used a lot with Spec. Typically alias is used to prevent circular ns dependencies (e.g., core -> specs -> core).

thheller21:11:35

alias was never a "sanctioned" way to do that. it was just abused for it.

kenny21:11:53

Sounds like it's the approach spec2 is taking.

thheller21:11:40

probably the thing to watch. if something lands in CLJ it should arrive shortly in CLJS as well

kenny21:11:56

So there is no workaround?

kenny21:11:35

Ok. Will follow that ticket.