Fork me on GitHub
#re-frame
<
2016-03-26
>
escherize03:03:12

good question @josh.freckleton. There are libraries to do that sort of thing but here's an approach you might find useful:

escherize03:03:04

basically it's a mashup of how reagent typically does input updating and dispatching via re-frame.

escherize03:03:45

(defn password-valid? [password-str] (> (count password-str) 5))
(defn email-valid? [email-str] (and email-str (re-matches #".*@.*" email-str)))

(defn validate [{:keys [password email] :as login-form}]
  (boolean (and (email-valid? email)
                (password-valid? password))))

(defn fake-login-view []
  (let [loading?   (subscribe [:loading?])
        login-form (subscribe [:login-form])
        email      (reaction (:email      @login-form))
        password   (reaction (:password   @login-form))]
    (fn []
      [:div
       [:form#login-form {:class (str "ui large form" (when @loading? " loading"))
                          :on-submit (fn [e] (.preventDefault e))}
        [:input {:type "text"
                 :name "email"
                 :placeholder "Email"
                 :value @email
                 :on-change #(dispatch [:update-login-form
                                        :email
                                        (-> % .-target .-value)])}]
        [:input {:type "password"
                 :name "password"
                 :placeholder "Password"
                 :value @password
                 :on-change #(dispatch [:update-login-form
                                        :password
                                        (-> % .-target .-value)])}]
        [:button.ui.button.fluid.large.violet
         {:on-click #(when (validate @login-form)
                       (dispatch [:login-request]))}
         "Submit"]]])))

escherize03:03:06

Then, here're the subscriptions:

(register-sub
 :signup-form
 (fn [db]
   (reaction (:signup-form @db))))

(register-sub
 :login-form
 (fn [db]
   (reaction (:signup-form @db))))

escherize03:03:32

and finally the update handler:

(register-handler
 :update-signup-form
 (fn [db [_ field value]]
   (assoc-in db [:signup-form field] value)))

afhammad11:03:32

Hi, I have this component structure, I’m trying to figure out why when prop1 changes, although two gets the updated prop, one doesn’t, even though it is being re-run but with the same initial value of prop1 every time.

(defn one [prop1]
  [:div prop1])
  
(defn two [prop1]
  [one prop1])
  
(defn three []
  (let [prop1 (subscribe [:get-prop-one])
    (fn []
      [two @prop1])]))

hoopes11:03:22

Is there a best-practice for naming subscriptions/handlers as the app grows larger? Looking at https://github.com/Day8/re-frame/wiki/A-Larger-App - would i be naming handlers something like :panel-1.do-something and :panel2.do-something? That's my first inclination, anyway, but if there's something more "oh, everyone just does it like this", I'd be curious to hear it. Thanks!

afhammad11:03:44

@hoopes: I’m new to re-frame but have started naming my subs/handlers namespaced like this :users/delete (since clojure uses / for accessing namespaced functions rather than .). Also for subs i’v settled on :users/all , :users/?id (gets a user by id), :users/?ids (gets multiple users by id), :feature/?user-id (you get the drift). I don’t know if there’s a common approach

hoopes11:03:02

that's an awesome idea - i think i'm gonna borrow that

nidu12:03:57

@afhammad: is it all the code? i reproduced your example here - http://cljsfiddle.com/#gist=e1e1929fbb53e592bdf9 approximately and it seems to work just fine

afhammad12:03:34

@nidu: Its not all the code, I just tried to simplify it for demo. Thanks for the fiddle, it must be something in my code, i’ll tinker a bit more and see

nidu12:03:09

@afhammad: if components one or two return fn instead of hiccup don't forget that parameters in component should match params of returned fn. That's often the case for me.

afhammad12:03:20

@nidu: not sure i got that. are you saying the factory fn and the fn it returns need to accepts the same params?

afhammad12:03:35

in my case both one and three return a fn but neither take any params, only parent defn accept params