Fork me on GitHub
#re-frame
<
2016-12-08
>
dragoncube01:12:03

@mikethompson why you are suggesting here to use synthetic namespaces (what is rationale)? https://github.com/Day8/re-frame/blob/master/docs/Namespaced-Keywords.md

samueldev01:12:19

I did a lein new re-frame yada yada and haven’t really changed anything in configuration; but when I lein cljsbuild once min & deploy to my S3 bucket, it’s still trying to do the figwheel connection stuff

samueldev01:12:31

is that not disabled when you do a min cljsbuild?

samueldev01:12:52

:figwheel true isn’t present in my min build info… nor in my dev one, for that matter :^

gadfly36101:12:57

@samueldev can you copy the console printout? My guess is a forgotten lein clean

shaun-mahood01:12:15

@dragoncube: not sure why other people use them, but I use them to keep things organized - your events, subs, fx etc. aren't automatically namespaced, so it's as much advice to namespace things as it is to use synthetic namespaces specifically - it just gives you the option to call it whatever you want.

samueldev01:12:20

all I’ve got is the typical browser output on failed figwheel ws connection

samueldev01:12:21

`Figwheel: trying to open cljs reload socket VM333:35 WebSocket connection to '<ws://localhost:3449/figwheel-ws/dev>' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED`

samueldev01:12:42

gonna try a lein clean

samueldev01:12:47

which’d be a classic mistake :X

gadfly36101:12:51

oh woops, i meant to say terminal instead of console. so what is printing after you did lein cljsbuild once min

gadfly36101:12:07

(i forget to clean all the time)

dragoncube01:12:50

@shaun-mahood the question is mostly why synthetic, but not existing ones

samueldev01:12:51

ah, turns out I’ve got some bad things happening @gadfly361 https://puu.sh/sHVRg/d0855caa85.png

samueldev01:12:09

I’m using :refer for those particular components

samueldev01:12:19

is that a no-no when doing min builds? do I need to qualify the namespace?

samueldev01:12:50

(trying anyway)

gadfly36102:12:06

hmm just looking at the first error, i would say the namespace itself may be misnamed ... dev builds are forgiving when a namespace is misnamed, but min builds arent

samueldev02:12:10

is it the same as I’d expect in clojure? (ns chalk.components.fact-blob) —> folder path chalk/components/fact_blob?

gadfly36102:12:14

a thing that often can happen is the file is called chalk/components/fact_blob and the namespace is named chalk.components.fact_blob ... when it should be chalk.components.fact-blob ... i.e. _ to -

gadfly36102:12:25

yeah, same as clojure

gadfly36102:12:04

so my second guess is there is a typo somewhere, may not be an underscore to dash thing since you are aware of that, just a spelling error or something.

shaun-mahood02:12:01

@dragoncube: Ahh, synthetic namespaces is mainly a choice of what works for your code - if your full namespaced event is something like :com.dragoncube.common.events/make-cube then you can just call it :common/make-cube - totally there if you need it, but if not then you don't have to worry about it.

samueldev02:12:43

ah yeah, I think it’s that I've got components in their own folder… so it expects a file called fact_blob.cljs under chalk/components/, when it is in fact under chalk/components/fact_blob/

samueldev02:12:42

yep that was it. additionally, uploaded to s3 and no longer seeing original figwheel issues 🙂

shaun-mahood02:12:59

I totally thought it was going to be some crazy lein template thing :) I just turn on the gadfly signal for those ones.

samueldev02:12:08

smh, I’ve written a monolithic re-frame app over the course of 2 months and am almost done (hence finally getting it up in s3)

samueldev02:12:23

and am only now realizing that this is valid for classes on hiccup: [:div.class1.class2]

samueldev02:12:42

my entire codebase is [:div {:class “class1 class2”}] ><

gadfly36102:12:53

well at least you only missed out on a little bit of sugar 😉 Sometimes I find myself writing it the long way tho ... i like my editor's syntax highlighting to bring attention to what classes i am using

dragoncube02:12:48

@shaun-mahood you can require namespace and alias it something shorter, the only advantage I see is that you are not introducing dependency, though in some situations it could become disadvantage (ex. advanced compilation)

shaun-mahood02:12:07

@dragoncube: I might be missing something, but when you register your events with reg-event-fx :ns/id I'm not sure how your aliased namespace in the cljs file matters - are we talking about the same thing?

dragoncube02:12:35

@shaun-mahood

==========================
(ns com.company.nav-menu.events)

(reg-event-fx ::my-event)

==========================
(ns com.company.nav-menu.views
  (:require [com.company.nav-menu.events :as nav-menu-events]))

(dispatch [:nav-menu-events/my-event])

mikethompson02:12:51

Note: in the #jobs channel, Oracle is advertising a reagent/re-frame position

shaun-mahood02:12:17

@dragoncube: does that work? I've never tried it. If you used a synthetic namespace there, you wouldn't have to require the specific events file in your views file.

dragoncube02:12:04

@shaun-mahood yep, we use it in our codebase

gadfly36102:12:22

To my understanding you are talking about the difference between these options

OPTION 1
==========================
(ns com.company.nav-menu.events)

(reg-event-fx ::my-event)

==========================
(ns com.company.nav-menu.views
  (:require [com.company.nav-menu.events :as nav-menu-events]))

(dispatch [:nav-menu-events/my-event])


OPTION 2
==========================
(ns com.company.nav-menu.events)

(reg-event-fx :nav-menu-event/my-event)

==========================
(ns com.company.nav-menu.views
)

(dispatch [:nav-menu-events/my-event])

gadfly36102:12:12

I would say 1 is more reliable, but brings in the dependency ... so yeah, matter of preference. I prefer ::

mikethompson03:12:18

When I register things, like events, I want to provide an id. A nice unique, meaningful id, which conveys meaning. The fact that I use a keyword, or a namespaced keyword or a synthetic namespaced keyword is, to me, not that important.

shaun-mahood03:12:08

@gadfly361: yep. The problem I have with option 1 is that the dependency isn't otherwise required, so you're adding a lot of dependencies across your program that are otherwise unnecessary. Purely a matter of preference and what makes sense for your project, though. Thanks for showing me something I didn't know @dragoncube, I didn't even realize that doing it that way was possible.

dragoncube03:12:36

in the doc I mentioned, specifically synthetic is bolded, that why I’m wondering why

shaun-mahood03:12:21

@dragoncube: probably a good idea to add a bit of discussion about the 2 approaches in there

mikethompson03:12:30

@dragoncube we've had a lot of questions over a period of time on this (how to organise bigger programs). So we give that advice. In the interests of clarity and the id being meaningful, I prefer a keyword using a simple, synthetic namespace, rather than a much longer true namespace which is harder to scan.

cmal03:12:07

re-frame is awesome, even Oracle choose to use it.

mikethompson03:12:08

But YMMV. You can use strings if you want :-)

mikethompson03:12:14

You can even do:

(def-event-db 
   [12 "hello I'm a teapot"]
   (fn [db v] .... ))

mikethompson03:12:09

providing that you later do this: (dispatch [[12 "hello I'm a teapot"] :other :params])

cmal05:12:35

Hi, I use the re-frame-template and put

(defmacro log [& args]
  `(do (.log js/console ~@args) nil))
in core.clj and (:require-macros [fcc-voting.core :refer [log]]) in events.cljs and it works well in one demo proj. But when I do the same thing in another demo , it shows
Compile Exception 
java.lang.AssertionError: Assert failed: Circular dependency detected, figwheel.connect.dev -> fcc-voting.core -> fcc-voting.events -> fcc-voting.core (not (some #{ns-name} seen))
. I wonder why the circular dependency happens and try to understand why should the template maintains both a clj folder and a cljs folder?. I found the following descriptions in the book Learning Clojurescript, is the reason have something related to this?
The fact that eval isn't available to the current ClojureScript runtime has direct implications for how macros work in ClojureScript as well. Since eval is only available to the JVM Clojure process, ClojureScript macros are also only able to be evaluated at compile time, rather than at run time, and they must be written in either a .clj (normal Clojure) file or a .cljc (reader conditional Clojure) file. Either way, code that is generated by a macro must target the runtime capabilities of ClojureScript, even if the macro itself is written in Clojure. In practice, this also means that ClojureScript macros need to be evaluated before we get around to actually calling them anywhere. The most common way of achieving this is to define them in another namespace than the one in which they are going to be called. They are then imported into the calling namespace using the special :require-macros keyword in namespace declarations, for instance:
       (ns my.namespace
         (:require-macros [my.macros :as my]))
A ClojureScript namespace can require macros from a namespace with the same name (that is, a my/namespace.cljs file could require macros from a my/namespace.clj file). There's one gotcha to be aware of with this—an imported macro and a function can share the same name. If that happens, ClojureScript will resolve the symbol to a macro if it's in a calling position, and to a function if it's not. 
Am I described my question clearly? Thanks.

cmal06:12:32

It seems that is because of I required [fcc-voting.core :refer [uuid]] this line prompts the circular dependency error.

dragoncube07:12:48

@mikethompson ok, so, it is mostly readability of shorter names, right?

cmal07:12:51

Hi, what is the recommended way of adding css styles to component in re-frame? inline or use garden/less/sass?

cmal07:12:11

I used

(defn polls-list []
  (let [polls @(re-frame/subscribe [:polls])]
    (.log js/console polls)
    [:div.polls-list
     (for [poll polls
           :let [title (:title poll)
                 id (:id poll)
                 k (str title id)]]
       ^{:key k}
       [:a {:href (str "#/polls/" id)
            :style {
                    :height "40px"
                    :width "100%"
                    :background-color "#fff"
                    :border "1px solid #ddd"
                    :margin-top "-1px"
                    :display "block"
                    :line-height "40px"
                    :border-radius "2px"
                    :color "inherit"
                    :&:hover
                    {
                     :background-color "#f00"
                     :text-decoration "none"
                     }
                    }}
        title])]))
but the pseudo class hover does not work.

cmal07:12:04

I found the hiccup way

[:a
             {:font-weight 'normal
              :text-decoration 'none}
             [:&:hover
              {:font-weight 'bold
               :text-decoration 'underline}]]
does not work inline either.

gadfly36108:12:18

@cmal i personally use garden

cmal09:12:12

@gadfly361 Thanks. Do you know how to insert <br/> in hiccup code? I've insert <br/> into hiccup code but it is escaped by default.

gadfly36109:12:25

@cmal hmm not sure i follow, but is this what you are after?

[:div {:dangerouslySetInnerHTML {:__html "<br/>"}}]

cmal09:12:11

@gadfly361 Thanks. I've been searching for this for hours.

cmal09:12:48

Does this [:div I used in re-frame is actually hiccup? So I can safely require hiccup.core in my views.cljs to do extra works?

akiroz09:12:49

It's hiccup-based syntax, it compiles to a JS virtual dom so no.

curlyfry09:12:03

@cmal: Regarding styles, I prefer just using a css processor like less, sass, or stylus

curlyfry09:12:39

I sometimes have the style file in the same folder as the component for convenience

cmal09:12:38

@curlyfry Do you know some articles for doing that?

akiroz09:12:50

personally I use garden for my styles because... clojure! 🙂

akiroz09:12:46

and I'm already writing my HTML in hiccup syntax, might as well do CSS in it too

cmal09:12:54

If it can import some css to use in component, I will not need to rewrite quite a lot of the css now.

curlyfry09:12:48

@cmal There's really nothing special about it, I just use classes like in any other html project!

cmal09:12:05

@akiroz see. I also write some css in garden. But I think it is also a good idea to write css in views. For now, jsx is doing inline css too. It show a trending to do component work for frontend.

curlyfry09:12:34

Or if you mean dividing it up into different files, it's a bit different for different preprocessors

curlyfry09:12:52

Usually you have some form of "main" style file that imports the rest

cmal09:12:30

Ok. I think for now I will still use less/sass. It's ok and will not cause much re-write works.

akiroz09:12:38

@cmal I've done inline styles in another project that uses a React/RadiumCSS stack it was pretty messy, I'd perfer to have a seperate css file for pages. I guess inline styles might work better for self-contained components

cmal09:12:20

Thanks for your guys' opinions.

mikethompson13:12:43

@dragoncube yep, readability. It is just an id

andre13:12:03

subscribe
  "Returns a Reagent/reaction which contains a computation"
That is, `make-reaction` here provides precisely none of the
  benefits of `reagent.ratom/make-reaction` (which only invokes its function if
  the reactions that the function derefs have changed value).

wasser14:12:26

@shaun-mahood: was there a technical problem with recording your Conj talk? It isn't posted with the others on ClojureTV

mitchelkuijpers14:12:30

It seems to be missing from the playlist of conj2016

wasser14:12:40

Good that it's there. With the live coding you really need the video to follow along. I'll let Alex know.

mitchelkuijpers14:12:25

Cool would be nice to ping alex indeed

shaun-mahood15:12:30

@wasser: thanks for catching that!

wasser15:12:20

Only good thing to come out of writing a trip report to get my expenses paid. Need to be thorough. I DM'd Alex over on #clojure-conj

wasser15:12:39

Just heard from @alexmiller - all fixed.

shaun-mahood16:12:42

@cmal: You can also do [:br] in hiccup

escherize18:12:45

What's the reason that we don't expose a version of dispatch and subscribe that wraps the internal state of re-frame?

escherize18:12:54

(namely re-frame.db/app-db)

akiroz18:12:30

not sure about dispatch but I think it'll be nice if there's a built-in sub for app-db because I use it in my signal graph sometimes so I need to write my own (reg-sub :app-db identity)

danielcompton19:12:19

@escherize can you expand on that? Don't quite understand the question

danielcompton19:12:20

@akiroz it's highly unlikely we'll provide an :app-db sub or similar, the idea of subscriptions is to get away from you having to couple your application state to your views

danielcompton19:12:59

In practice it is common for people to make subscriptions to subtree's of a view for a certain section. But I wouldn't recommend a subscription to the root

danielcompton19:12:54

Also, it will not be particularly efficient, as that subscription will rerun itself any time anything in app-db changes. Most of the time of course there will be no change in data, so the data flow will stop there, but you still have a reaction running on every change

shaun-mahood20:12:03

@danielcompton: I think I might have confused myself on something with subscriptions during my talk prep, can you clarify something for me? If I have an app-db {:a [1 2] :b [3 4]}, and subscriptions (reg-sub :a (fn [db _] (:a db))) (reg-sub :b (fn [db _] (:b db))) (reg-sub :all (fn [db _] db)) Assuming I have a view that uses all 3 subscriptions, which subscriptions will re-run if I change the value of the app-db to {:a [1 2 3] :b [3 4]}? Is sub :b able to tell that the value it depends on hasn't changed automatically, or does it have to run its query function (:b db) and check the value to figure that out?

danielcompton21:12:56

All of them will run

danielcompton21:12:19

If the input changes, then the sub will run

danielcompton21:12:30

In all 3 cases, db is changing so the sub runs it's fn

danielcompton21:12:22

However in a well architected re-frame app, you would usually have a handful of subscriptions corresponding to major sections of your app-db, and then create subscriptions off of that for use in your views

danielcompton21:12:51

That way, you minimise the number of subscriptions that need to run, and build a more elegant signal graph

danielcompton21:12:45

To be clear, there's a few phases involved here: 1. subscription data source changes 2. leads to subscription rerunning (always) 3. That may lead to the data returned by the subscription changing. 4. Which would then trigger further subscription updates and eventually a change in the view if view data changed

shaun-mahood21:12:57

Ok good, my understanding was correct and I didn't misinform everyone at the Conj 🙂

andre21:12:25

4. Which would then trigger further subscription -where should be these further subscribtions?

andre21:12:39

i know about reaction on subscription

danielcompton21:12:51

@andre other reg-subs which use :a and :b as inputs

danielcompton21:12:59

rather than taking a db directly

andre21:12:21

sorry. how can i reg-sub using ;a as input?

andre21:12:24

reg-sub has only a db as input, no?

andre21:12:18

i should read the docs again 😉

andre21:12:32

i found There's 3 ways this function can be called

andre21:12:39

i know only one 🙂

mikethompson23:12:55

@andre read https://github.com/Day8/re-frame/blob/master/examples/todomvc/src/todomvc/subs.cljs You could do this:

(reg-sub 
    :something 
   (fn [_ _] 
        (subscribe [:a]))
   (fn [a v] 
      ....))
OR, using the syntactic sugar, this:
(reg-sub 
    :something 
   :<- [:a]
   (fn [a v] 
      ....))