This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-03
Channels
- # adventofcode (6)
- # bangalore-clj (1)
- # beginners (15)
- # boot (4)
- # cider (14)
- # clara (1)
- # cljs-dev (1)
- # clojure (115)
- # clojure-art (1)
- # clojure-france (1)
- # clojure-greece (1)
- # clojure-korea (9)
- # clojure-russia (1)
- # clojure-spec (62)
- # clojure-taiwan (1)
- # clojure-uk (18)
- # clojurescript (5)
- # component (1)
- # cursive (3)
- # datascript (2)
- # datomic (17)
- # devcards (2)
- # editors (4)
- # emacs (65)
- # events (2)
- # funcool (4)
- # hoplon (92)
- # jobs (6)
- # london-clojurians (1)
- # luminus (1)
- # midje (2)
- # mount (1)
- # off-topic (1)
- # onyx (51)
- # protorepl (6)
- # re-frame (116)
- # reagent (7)
- # ring (2)
- # spacemacs (2)
- # specter (4)
- # untangled (1)
- # yada (1)
Hi, I have just started to use re-frame and there is some problem. I'm encountering re-frame: overwriting :event handler for: :initialize-db
and some similar warnings. And then (...core.cljs, ... events.cljs) Figwheel: NOT loading these files
. What is the problem? Is there any error with my project settings or something else? thanks.
when I try to trigger the events, I got some error: Uncaught Error: nth not supported on this type function Number() { [native code] } ... ... at events.cljs:21
The overwrite warnings is not a problem. Figwheel is reloading a file, and when it does, the registrations are occurring again. re-frame is warning you in case that's a problem.
(ns data-nav-reframe.events
(:require [re-frame.core :refer [reg-event-db]]
[data-nav-reframe.db :as db]
[dirac.runtime])
(:require-macros [data-nav-reframe.core :refer [log]]))
(dirac.runtime/install!)
(reg-event-db
:initialize-db
(fn [_ _]
db/default-db))
(reg-event-db
:set-active-panel
(fn [db [_ active-panel]]
(assoc db :active-panel active-panel)))
(reg-event-db
:left-bar-select
(fn [db [_ [index]]]
(log db)
(log index)
(assoc db :left-bar-active index)))
I'm guessing that last one should be:
(fn [db [_ index]]
and not (fn [db [_ [index]]]
@mikethompson thanks, I'll try that
The overwrite warnings is not a problem. Figwheel is reloading a file, and when it does, the registrations are occurring again. re-frame is warning you in case that's a problem (which it isn't)
@mikethompson that is the problem. Thank you!
@shaun-mahood great talk, I am glad that re-frisk did not disappoint 🙂
{:http-xhrio { :on-success [:good-post-result :good-post-result2]}}
сan i provide vector of post-result events?only one event
in @shaun-mahood talk he said you can stop propagation on coeffects, so, for ex. i have coeff for getting value from local storage and if there is no value i want to do not continue
Hi, is this :let
in for
loop right? I found the value of selected?
did not get a valid value. I did not find such a pattern in the todomvc demo of re-frame
. Just want to do (let [...] (fn [] ...))
in a for
loop.
(defn left-bar []
(fn []
[re-com/v-box
:children (for [index (range (count icons))
:let [name (:id (nth icons index))
selected? (subscribe [:selected? index])]]
^{:key index}
[re-com/box
:size "80px"
:child [re-com/md-icon-button
:md-icon-name name
:size :larger
:on-click #(dispatch [:left-bar-select index])
:style (left-bar-btn-style index selected?)]
])
]
))
@andre interceptors fns (:before and :after) are passed a context
which is this:
https://github.com/Day8/re-frame/blob/master/docs/Interceptors.md#what-is-context
Your :before
and :after
can modify :queue
and :stack
within the context
In that way they can change the event handling process
Of course, they are normally changing :coeffects
or :effects
BUT in advanced cases they can change the entire pipeline via :queue
and :stack
https://github.com/Day8/re-frame/blob/master/docs/Interceptors.md#self-modifying
So if a :before
interceptor fn wanted to ADD further interceptors it would add them to the :queue
On the other hand, if it wanted to abort the process, it would clear out the :queue
and :stack
@cmal should you have used @selected?
or maybe just do selected? @(subscribe [:selected? index])
note the @
You don't need that fn
inside the defn
@mikethompson thanks. I found all the v-boxes were re-rendered each time I click the button, so I moved the subscribe
to the outside of the v-box. but this time left-bar-btn-style
re-computation was not triggered when I click the button. but the app-db
does changed , and reg-sub
does run.
(defn left-bar []
(let [selected (subscribe [:left-bar-selected])]
(fn []
[re-com/v-box
:children (for [index (range (count icons))
:let [name (:id (nth icons index))
selected? (= @selected index)]]
^{:key index}
[re-com/box
:size "80px"
:child [re-com/md-icon-button
:md-icon-name name
:size :larger
:on-click #(dispatch [:left-bar-select index])
:style (left-bar-btn-style index selected?)]
])
]
)))
@mikethompson thank you for such a detailed response, but event function will be called anyway, you can just clear interceptors queue?
Sorry to bother. I've made a mistake in the reg-sub
. This time it works perfectly. Thanks for you today. You really helped me alot
@andre the event handler function is wrapped in an interceptor, on the end of the queue.
So if the queue is cleared, so too is the event handler
Not sure that you mean
(reg-cofx ;; new registration function
:local-store
(fn [coeffects local-store-key]
(assoc coeffects
:local-store
(js->clj (.getItem js/localStorage local-store-key)))))
Ahh. Some misunderstanding here.
Remember:
1. these cofx handler are done as a last step by the :after
of the last Interceptor in the queue
2. cofx handler are not Interceptors
3. So they dod not have the option of abandoning the process.
4. There is no guarantee about the order in which cofx get called
I'm editting the above
yes. i need to dig more, thank you, i want to make infographics to understand clear how it works
That would be good !!
and i thinking now, i'm naming my events using suffix, f.e. :get-data-fx , or :update-value-db, it's clear to read, and i want to color events in re-frisk by this suffix, it should be easy to find pure or effectfull events in the list
quick Q - does [a-multimethod]
where the multi-method resolves to my-cmp
change any lifecycle things compared to [my-cmp]
. Are they essentially interchangeable? I mean specifically in the sense that (my-cmp)
is very different to [my-cmp]
. This is for a very optimised (in terms of re-rendering) table with a high number of rows.
I assume not. My assumption is that the multimethod resolution is at a lower level than reagent, but you know what happens when you ass-u-me 🙂
(and huge congrats to @mikethompson, @danielcompton and the team) - re-frame is coming on leaps an bounds. The simplicity of the interceptors
/`coeffects handlers` is sublime. Like all great abstractions it initially receives a ‘huh?’ followed moments later by the lightbulb moment 🙂.)
(and if that butter leads you to answer my question above then all the better ;-))
@colin.yates we even have a logo these days :-) https://github.com/Day8/re-frame/blob/develop/docs/The-re-frame-logo.md
@colin.yates I'm not aware of multimethods changing lifecycle related behaviour
But I am a bit suspicious of using multimethods around Reagent
ok, that’s fine - I think I will steer clear then. The lein
template (https://github.com/Day8/re-frame-template) does include them as a way of rendering the current panel though.
I thought we'd removed that
I generated it last night and it produced:
;; home
(defn home-panel []
(let [name (re-frame/subscribe [:name])]
(fn []
[:div (str "Hello from " @name ". This is the Home Page.")
[:div [:a {:href "#/about"} "go to About Page"]]])))
;; about
(defn about-panel []
(fn []
[:div "This is the About Page."
[:div [:a {:href "#/"} "go to Home Page"]]]))
;; main
(defmulti panels identity)
(defmethod panels :home-panel [] [home-panel])
(defmethod panels :about-panel [] [about-panel])
(defmethod panels :default [] [:div])
(defn show-panel
[panel-name]
[panels panel-name])
(defn main-panel []
(let [active-panel (re-frame/subscribe [:active-panel])]
(fn []
[show-panel @active-panel])))
this was a result of lein new re-frame pj-rf +test +routes +devcards
We should remove that use.
would a PR with a simple case
be sufficient?
Would be great.
Oooh, my first lein
template journey - I will send it over later today then.
Are there any re-frame components with custom rendering? I’m not using bootstrap so re-com isn't a good match for me. For me it would be ideal to have something similar to re-com but with a possibility to provide custom rendering. I.e. separate the logic from the hiccup. Is there something like this out there?
Not that I've seen
I'd be tempted to fork re-com and make it render the way you want it.
There's just so many possible needs
@mikethompson https://github.com/Day8/re-frame-template/pull/40 is all yours. Comments appreciated which I will action after lunch.
Thanks! Have commented, but will leave it to Matthew to merge
multimethods are fine for form-1 components aren't they @mikethompson ? which covers a lot of ground now that form-1s can reasonably subscribe...
Hi, I found the reagent and re-frame todomvc both have some :keys
for todo-item
, but I dont know what the keys means. I've write the following code but the compiler keep warning me that Every element in a seq should have a unique key
. Where is the problem? Thanks!
(defn show-panel-child [id text]
[:div.show-panel-child
[:div.child-text
text]
[:div.child-delete
[re-com/md-icon-button
:md-icon-name "zmdi-delete"
:size :smaller
:on-click #(dispatch [:delete-show-panel-child id])
]]]
)
(defn show-panel []
[:div.show-panel
(let [children @(subscribe [:show-panel-child])]
(for [child children
:let [id (:id child)
text (:text child)
div (show-panel-child id text)]]
^{:key id}
[re-com/box
:child div
:style {
:background-color "white"
:margin-bottom "10px"
}])
)])
the code of todo-item
in todomvc demo
is as follows:
(defn todo-item
[]
(let [editing (reagent/atom false)]
(fn [{:keys [id done title]}] ;;; <=== this :keys
[:li {:class (str (when done "completed ")
(when @editing "editing"))}
[:div.view
[:input.toggle
{:type "checkbox"
:checked done
:on-change #(dispatch [:toggle-done id])}]
[:label
{:on-double-click #(reset! editing true)}
title]
[:button.destroy
{:on-click #(dispatch [:delete-todo id])}]]
(when @editing
[todo-input
{:class "edit"
:title title
:on-save #(dispatch [:save id %])
:on-stop #(reset! editing false)}])])))
@cmal are you sure id
is not nil? Also, calling (show-panel-child id text)
would be more performant as [show-panel-child id text]
at which point you might want to rename it to panel-child
😉. Try adding (.log js/console (clj->js children))
between the for
and the let
.
@cmal, ah, I think you are also confusing the use of :keys
when destructuring in Clojure and also React’s requirement/wish that every child in a dynamic sequence has a unique key
. For reagent (the Clojure binding to React), you can provide the key
either as meta-data or as a :key
in the props map. So ^{:key id} [comp…]
is equivalent to [comp {:key id} …]
(1/2)
@cmal - the :keys
in the todo example have nothing to do with React or reagent, but is simply a convenience Clojure provides called destructuring. If I have a map m of {:a 1 :b 2 :c 3}
then if I want to interrogate that map I can do either (:a m)
or {:keys [a]}
which creates a local var called a
and assigns it the value of (:a m)
. (2/2)
@cmal - http://clojure.org/guides/destructuring for more info
Yes I am keen to know if multimethods/form-1 has lurking problems since I have just re-written to use that and it seems to work and provides an elegant solution over the use of case
etc...
in a complex app the use of case to select among view components surely has to be a horrible choice
@andre: re-frisk worked great, without it I couldn't have done the talk the way I wanted - thanks for all your work on it!
@colin.yates @mikethompson Will accept and deploy to clojars when im back at a computer, thanks for the PR! :)
I published a cleaned up and properly working version of the code I used for my re-frame talk at the Conj https://github.com/smahood/re-frame-conj-2016
@andre that looks accurate
@mikethompson this is a draft, i posted it for the review, i'll try to make it more intuitive and straight 🙂
It is a hard thing to show because there is time involved
i re-read your answer, i was talking about red function on the picture, why did you say
1. these cofx handler are done as a last step by the :after
of the last Interceptor in the queue
4. There is no guarantee about the order in which cofx get called
Sorry, i got confused there. I was writing cofx but was thinking fx
There is no ordering of effects
@mikethompson thank you for the re-frame, i'm really enjoing reading the docs, and working with re-frame
np. I'm glad you like it. I'm working away on better docs in develop
/docs/WIP
But the struggle is to explain things that happen over time
And there's a bit of that with subscriptions etc
Plus, the interceptor stuff, as your diagram shows
Yes, but result is very good, just need to carefully read. In the first time I read between the lines and paid for it, the second time when re-read carefully, wondering how everything is well documented
I appreciate you saying that. There's blood sweat and tears in those docs. :-)
Way, way more work than the code :-)