Fork me on GitHub
#clojurescript
<
2019-09-25
>
Oliver George02:09:18

Just had a doozy of an advanced compilation bug. We're using Leaflet which uses a global variable "L" (e.g. window.L). The advanced compilation process produces short variables so L gets clobbered (turned into cljs.core/conj in fact).

Oliver George02:09:46

Since our code doesn't reference window.L directly our infer externs didn't kick in to protect it.

Oliver George03:09:03

I'm waiting for a "doh!" moment. Seems rather unsafe to randomly clobber global (window) vars.

Oliver George03:09:40

Ah, I'm using deps.edn instead of the lein cljsbuild plug-in. Cljsbuild sets :output-wrapper true for advanced builds

awb9909:09:04

Are there some reagent experts here? I am trying to find a reagent/react event to hook into. I want to see if any of the arguments that have been passed have changed. I tried a lot: :reagent-component-will-receive-props :component-will-receive-props :get-snapshot-before-update :should-component-update . It seems that ONLY the render function seems to see the new argv.

herald12:09:27

Have you tried :component-did-update (fn [this old-argv old-state snapshot]) then use reagent.core/props on this to get new props http://reagent-project.github.io/docs/master/reagent.core.html#var-props

✔️ 4
lilactown13:09:19

@hoertlehner what are you trying to do specifically?

awb9915:09:48

I have written a component, that fetches and passes it to its child-component.

awb9915:09:58

[fetch-data-container {:month 10} :bad [:h1 (get-in @state [:result :data])]]

awb9915:09:35

I have a couple of components, that need to request data with :api-route and :query-params.

awb9915:09:47

This components just display the received data.

awb9915:09:01

In order not to have the api request logic in each of this pure ui components,

awb9915:09:04

I made this wrapper.

awb9915:09:07

The wrapper works

awb9915:09:45

When I use this wrapper in another coponent that passes the query params to it,

awb9915:09:48

then it will not update.

awb9915:09:51

The reason is,

awb9915:09:01

that this will ONLY trigger the re-rendering,

awb9915:09:10

but will not fire new-props.

awb9915:09:20

Now I could do a work-around,

awb9915:09:31

where in the render function I set an atom with the current query params,

awb9915:09:33

and then add a watcher,

awb9915:09:37

that does the fetching.

awb9915:09:45

But this means one more leg to keep track,

awb9915:09:52

and making sure the watcher gets shutdown correctly.

awb9915:09:09

So I would prefer to implement some react props-changed event,

awb9915:09:14

and in there do the re-fetching.

awb9915:09:01

Regardng react version...

awb9915:09:04

I have no idea

awb9915:09:06

[org.clojure/clojurescript "1.10.339"]

awb9915:09:21

[reagent "0.8.2-SNAPSHOT" :exclusions [cljsjs/react cljsjs/react-dom]] ; reagent has older react references than material-ui

awb9915:09:47

[cljsjs/material-ui "3.2.0-0"]

lilactown15:09:01

Are you using lein?

awb9915:09:05

This is what I had to do to get reagent and material ui running.

awb9915:09:07

Yes lein.

lilactown15:09:37

You can do lein deps :tree and search for React

lilactown15:09:53

To see what version you have

lilactown15:09:41

To clarify, you don't see any of the printlns in component-will-receive-new-props ?

awb9915:09:36

It is quite confusing,

awb9915:09:46

which keys I have to use for the functions.

awb9915:09:02

If I understand reagent correctly,

awb9915:09:11

then only the first argument will be the react PROPS.

awb9915:09:20

This is why I put the query-url parameter first,

awb9915:09:29

so I am sure that this would be the react props.

awb9915:09:43

When I use getSnapshotBeforeUpdate

awb9915:09:50

then it will do a warning

awb9915:09:04

saying it disables componentWillMount/ReceiveProps/Update.

lilactown15:09:07

can we remove all of the ones except the stuff we care about?

lilactown15:09:18

your should-component-update might also be blocking it

lilactown15:09:25

it’s really hard to say from looking at the code

lilactown15:09:48

so let’s delete that, get-snapshot-before-update, reagent-component-will-receive-props, etc.

awb9915:09:20

:reagent-component-will-receive-props

awb9915:09:27

:component-will-receive-props

awb9915:09:37

which of this 2 should be used?

awb9915:09:41

I found both versions.

awb9915:09:59

fetch-comp component-did-mount {:month 10} repl.cljc:251:17 fetch-comp component-will-update {:month 10} repl.cljc:251:17 fetch-comp component-did-update: :bad

awb9915:09:05

in my dev-card sample

awb9915:09:14

this is what fires when the component is first mounted.

awb9915:09:20

fetch-update error! repl.cljc:251:17 fetch-comp component-will-update {:month 10} repl.cljc:251:17 fetch-comp component-did-update: :bad

awb9915:09:27

and this when it gets the fetch error.

awb9915:09:24

but when I use this component

awb9915:09:28

and give it different query params,

awb9915:09:33

then there are no events.

awb9915:09:54

I think all that happens,

awb9915:09:02

is that reagent calls the render function with changed parameters.

awb9915:09:15

this is why I am considering updating a local state on render.

awb9915:09:23

but this is really crazy.

lilactown15:09:33

according to the API docs, component-will-receive-props

lilactown15:09:13

it’s not clear to me what you’re actually doing, how the error you’re talking about might relate, etc.

lilactown15:09:27

if you want to setup a repo with code that compiles, I’ll poke at it for you

awb9915:09:07

what is your git handle?

lilactown13:09:34

and what version of React do you have installed in your project?

lilactown13:09:40

the answer might vary depending on those two answers

lilactown16:09:08

does anyone know why we might see a substantial difference between lein-cljsbuild/figwheel incremental compiles vs. shadow-cljs?

lilactown16:09:29

with lein-figwheel, compilation takes ~20s for some changes. with shadow-cljs, it takes <1s for the same changes

thheller16:09:44

might be :recompile-dependents? defaults to true in figwheel I believe?

lilactown16:09:37

yes, that’s my current hypothesis now after reading your blog on hot reload again 😄

lilactown16:09:49

I wonder if it defaults to true with figwheel-main

jaime18:09:04

Hi, what am I doing wrong here? The error is shadow-cljs - [reload failed] Failed to load my/app.cljs: [object Object] is not ISeqable

(ns 
  (:require [reagent.core :as r]))

(def todos (r/atom (list {:id 1 :title "Task 1"}
                         {:id 2 :title "Task 2"})))

(defn todo-list [items]
  [:div
   (for [todo todos]
     [:div (:title todo)])])

(defn app []
   [todo-list todos])


(r/render [app]
          (js/document.getElementById "app"))

andy.fingerhut18:09:49

Probably try (for [todo @todos] instead of the for you have now.

andy.fingerhut18:09:01

The value of todos is not a sequence, but an atom, and you cannot iterate over an atom

andy.fingerhut18:09:49

@todos could also be written (deref todos) -- @todos is just a short-hand syntax for (deref todos)

andy.fingerhut18:09:53

Warning: I know nothing about reagent and its conventions -- I do know something about ClojureScript

jaime18:09:26

@andy.fingerhut Yes, you’re right! defining the todos as (removing the atom) worked!

(def todos (list {:id 1 :title "Task 1"}
                 {:id 2 :title "Task 2"}))

jaime18:09:30

thanks for explaining important concepts. something I have to read

andy.fingerhut18:09:42

FYI, given that there is a literal syntax for vectors, and vectors and lists are often fairly interchangable in Clojure (at least in many contexts), you could also write that as

(def todos [{:id 1 :title "Task 1"}
            {:id 2 :title "Task 2"}])
if you wanted to.

jaime18:09:38

make sense. do we have to consider if we are iterating or inserting in first/last element? Or it wont matter that much perf wise?

jaime18:09:14

I mean, list is fast when iterating sequentially or inserting in first element.

andy.fingerhut18:09:21

Yes, hence why I said 'in many contexts', not 'in all contexts'. The primary difference between lists and vectors in Clojure is that lists are fast for inserting new elements at the beginning, and vectors at the end. And that vectors have fast lookup by index, whereas lists are linear time for that. For traversing their elements as a sequence, their performance is so close it well as may be identical.

❤️ 4
jaime18:09:37

good to know. still wrapping up what I’ve read so far 😅

jaime19:09:31

The .-which in this line seems to be a js object interop? https://github.com/reagent-project/reagent/blob/master/examples/todomvc/src/todomvc/core.cljs#L39 Where can I find the api for these? Can’t find it in the cheatsheet https://cljs.info/cheatsheet/

thheller19:09:55

@jaime.sangcap are you asking about JS interop in general or .-which in particular?

dpsutton19:09:39

JavaScript Interop on that cheatsheet

❤️ 4
jaime19:09:40

@thheller I think for now I’m curious what is .-which and where it is coming from. Because in javascript, there is no method like that in KeyboardEvent? But you can also tell me more about JS interop in general, I would appreciate that and would help me alot get started

thheller19:09:52

.-which is accessing the .which property

jaime19:09:09

OH! I’m an idiot 😄 Then it means it is just direct JS interop

jaime19:09:49

Make sense now. Thanks @thheller @dpsutton

parens 4
Ian Fernandez22:09:40

thread macros works with cljc?

Ian Fernandez22:09:15

(-> app #?(:clj http-driver-clj :cljs http-driver-cljs))