Fork me on GitHub

@mruzekw no, fulcro css uses real css, which is not available in RN


Okay, thanks. Yeah I got it to work with vanilla StyleSheet


Slightly unrelated, I am having trouble with hooks though


(defsc Root [this props]
  {:use-hooks? true}
  (let [is-desktop (rresp/useMediaQuery #js {:minWidth 400})]
      {:style (.-container styles)}
      (ui-text {:style (.-text styles)} is-desktop))))


"react": "^16.10.2",


[com.fulcrologic/fulcro "3.1.8"]


react-dom.development.js:16238Uncaught Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: ...


Am I missing something?


Figured it out, it was indeed one of the issues in the list


The react/react-dom version was different between my project package.json and my fulcro version


When I do df/load!, it does not create the rootedge, I have been trying using the {:target [:component/id ::uif/account-list :account/farms]} , this creates a new entry in the db, but doesnt create a root edge like in the video tutorial.


@murtaza52 not sure what you mean “like in the tutorial”…I beleive the tutorial shows you that is the default place it goes (only) if you don’t specify a target.


(df/load! app                                                         :all-accounts                                                         uif/Account)
@U0CKQ19AQ When I do the above it loads the data under the :all-accountskey but nothing under the :root key in the DB.


Got it, its the initial state which creates the root edge, not the data fetch !


@U0CKQ19AQ other than the root element, if I am loading the data from a remote, what is the purpose of the initial-state ?


if you only ever load it, initial state serves no purpose. It is for generating the first “frame” of your reified view for initial render.


anyway, it’s what it should say, because that’s the correct behavior

Eric Ihli20:05:38

Can anyone explain this behavior? The component renders form inputs with an initial state that sets the values to empty strings. As soon as one of the inputs `onChange` is triggered and the value is updated, the component is getting re-rendered with only that modified input field as a key in props.

Chris O’Donnell22:05:26

Can you share more of your code? It's hard to say from what you've shared.


I have this helper for debugging form state, it may help clarify what's happening, but i'm not sure, as it could be a number of things. To use it pass it your form validator and the component and it shows you the form state

(defn form-debug
  "show table of form fields for a component with value and validation state.
  validator component instance"
  [validator com show?]
  (let [props (comp/props com)
        {:keys [form-fields]} (comp/component-options com)
        form-ident (comp/get-ident com)]
    (when show?
        (dom/h4 :.ui.violet.message (str "Form fields for " (pr-str form-ident) ":"))
        (dom/table :.ui.celled.table.striped.yellow
            (dom/tr (dom/th "field") (dom/th "value") (dom/th "valid state")))
            (dom/tr {:key "all"} (dom/td "Entire form") (dom/td "n/a") (dom/td (pr-str (validator props))))
            (map #(dom/tr {:key (str %)}
                    (dom/td (str %))
                    (dom/td (pr-str (props %)))
                    (dom/td (pr-str (validator props %))))

Eric Ihli00:05:16

Thanks dvingo. I'll try that out. Here's the code

Eric Ihli00:05:05

Ah. I still have a lot of misunderstandings in my head. Never used React, new to Clojure, and Fulcro is a lot to take in.

(defsc Root [this {::keys [user-list]}]
  {:query [{::user-list (comp/get-query UserList)}]
   :initial-state {::user-list {}}}
    (ui-user-form (comp/get-initial-state UserForm)))
Fixed by (side-note: removed unrelated user-list code) ->
(defsc Root [this {::keys [user-form]}]
  {:query [{::user-form (comp/get-query UserForm)}]
   :initial-state (fn [params] {::user-form (comp/get-initial-state UserForm)})}
   (ui-user-form user-form)))


ahh, well glad you found it!

Jakub Holý (HolyJak)15:05:50

Starting with ClojureScript, React, and Fulcro, that might be too much. In general I recommend starting with simple Clojure apps, then ClojureScript, then a simple cljs framework such as Reagent, then Fulcro.


Hi, I'm trying to create an AWS Cognito authentication ui state machine. The state machine is quite similar to the demo presented in Fulcro Part 17, of the Fulcro 3 video tutorials. My login mutation can return session related information, similar to the tutorial such as user/id, user/email, user/valid?, but can also give back some error information too which seems to belong more to the login table (again from the video tutorial where you have a session table containing user info and a login-form table that contains username, password form fields). In my trigger-remote-mutation call I'm passing:

{::uism/mutation-remote :cognito
 ::m/returning user-class
 ::dt/target [:session/current-user]
 ::uism/ok-event :event/ok
 ::uism/error-event :event/error}
What's the best way of putting some of the return information one table and the rest in another in a ui state machine?


You can do that in your handler for :event/ok. Here's an example from an app where I handle updating the client db after a successful entity creation - the relevant parts are apply-action in the success handler

          {::m/returning    item-cls
           ::sm/ok-event    :event/success
           ::sm/ok-data {:form-cls form-cls :entity entity :append append}
           ::sm/error-event :event/failed}
      (sm/activate :state/submitting)

;; in handlers section:
{:event/success {::sm/handler                     
                        (fn [{{:keys [form-cls entity append]} ::sm/event-data :as env}]
                          (-> env
                            (sm/apply-action #(merge/merge-component % form-cls entity :append append))
                            (sm/apply-action #(cu/reset-form* % (sm/actor->ident env :actor/form)))
                            (sm/assoc-aliased :server-msg "Success")
                            (sm/set-timeout :clear-msg-timer :event/reset {} 2000)
                            (sm/activate :state/success)))}}


Perfect, thank you @danvingo, that's exactly what I needed.