Fork me on GitHub

@tony.kay it is in the doc-string, that is where I found it. And if I understand you correct we can use the doc-string as the definitive guide as to what the public API is?


“definitive” is a strong word for free open source. I strive to make all documentation as correct and complete as possible. If it is mentioned anywhere and works, then it is as official as it gets.


Is there some example available how to create bootstrap forms in Fulcro?


So, there is a ton of variability in the question. Bootstrap is CSS, and it also has non-react js components. There is not a great way to use the js components (though I wrote some wrappers for the css at one point if you look in F2 source or earlier…abandoned, but semi-working). You are more likely asking about how to do form state and interaction, which has nothing to do with bootstrap. The book goes into quite a bit of detail on using Form State helpers. In your example below you seem to want a modal, which is whole other thing that has nothing in itself to do with forms other than they sometimes “hold” forms.


But this is probably even lack of bootstrap/react understanding rather than fulcro problem itself..


:onChange     (fn [e] (comp/transact! this [(ui-mutations/update-add-connector-modal-form
                                             #:add-connector-modal{:id    id
                                                                   :field (.-id (.-target e))
                                                                   :value (.-value (.-target e))})]))


Is something like that a correct approach?


Hello, I have component that I have set initial state on it, it gets normalized in db alright but it doesn't show up in the props any help or ideas please 🙂 ?


did you destructure them and pass them through??? There is nothing magic about the props…they are a tree passed from root


I'm routing to the main sub component that have initial-state, so it acts like root (?) in that context, maybe because of that??


I cannot possibly answer your question any better without seeing code.


You have a point, I tried to shrink code to it's basic.

;; router 
(dr/defrouter ProjectPanelRouter [this props]
  {:router-targets [ActionList]} )
;; where we route to our component with initial state
(defsc ProjectPanel [this {:project-panel/keys [router] :as props}]
  {:query           [{ :project-panel/router (comp/get-query ProjectPanelRouter) } ]
   :ident   (fn [] [:component/id :project-panel])
   :initial-state {:project-panel/router {}}
   :route-segment   ["project-panel"]

    (ui-button {:onClick #(dr/change-route this (dr/path-to  ActionList {:action-list/id  (random-uuid)} ))})
    (ui-project-panel-router router))})
;; the target route (with init state)
(defsc ActionList [this {:action-list/keys [id actions] :as props}]
  {:query [:action-list/id {:action-list/actions (comp/get-query ActionRow)}]
   :route-segment   ["action-list" :action-list/id]
   :ident  :action-list/id
   :initial-state (fn [params] {:action-list/id (random-uuid)
                                :action-list/actions [(comp/get-initial-state ActionRow {:owner "Owner" :action "Action" :id 1})
                                                      (comp/get-initial-state ActionRow {:owner "Owner2" :action "Action2" :id 2})]})
                                        ;:initial-state {:project/id 1 }
  (map ui-action actions))

;; child component 
(defsc ActionRow [this {:action/keys [action owner status due-date] :as props}]
  {:query [:db/id :action/action :action/owner :action/status :action/due-date]
   :ident [:action/id :db/id]
   :initial-state (fn [{:keys [owner action id]}] {:action/owner owner :action/action action :db/id id})}
   (dom/li {} action)
   (dom/li {} owner)))
I have also noticed that using lambda for initializing the state of the router (in component where we route) doesn't work as the template one. Thank you 🙂


I have noticed when having ident that depends on props, it doesn't work (props don't get passed from init state), having an ident which doesn't use props did the trick (ActionList comp) but still don't get it, why can't props that come through init state can't be used in the ident.


so, props do get passed from init state, and the ident function really must use the data that is passed in props or they cannot work. I don’t understand that statement. OH, I think you misunderstand the diff between initial state as a lambda and as a map.


as a map, it is magic.


The equiv initial state in ActionList is:

:initial-state {:action-list/id (random-uuid)
                :action-list/actions [{:owner "Owner" ...} { :owner "Owner2" ...}]}


perhaps that was your problem? I’m pretty sure there is a misunderstanding in there somewhere, but the code as you show it above looks fine as far as I can tell.


how are people handling tracking routing history in fulcro apps? seems like I can just transact a mutation to store a route path on the app state in the will-enter fn of my component and wherever else the route changes. anything I’d be missing with that approach?


Why aren’t you just using the goog History API?


or are you not using the URL to track history? You’re suggestion has merit in some circumstance.

Jakub Holý (HolyJak)23:02:26

I assumed that a router just passes through whatever props it gets (possibly dissocing it's own) to its targets so that if I do (ui-router1 (assoc router :xxx 1)) I would get (= 1 (:xxx props)) in the routing target. Or not?


the router has it’s own props, and it is never appropriate to do that to props that come from a query (because of the possibility of localized UI refresh of the child, which would be missing that assoc)

Jakub Holý (HolyJak)10:02:35

Thank you! So I guess what is happening in practice, for the first target, is something like (pseudocode):

((factory MyFirstTarget) (merge computed-props (:alt0 props)))
so that we do pass down the props from the query + computed props. Right?


If you just follow that link and read the macro code, you can quickly see exactly what it is doing…computed is carried as a special prop if it is to one (a map) and as metadata if to-many….but in either case Fulcro knows that the data was computed and can re-supply it on targeted refresh.

Jakub Holý (HolyJak)19:02:58

I would dispute the "can quickly see" part 😅 I have studied the code yesterday (before asking) but failed to grok it fully. Thank you!


agreed 😄 if you’ve read and understood the reason for computed, that is, then it is a single line of code in the macro that I linked you to, which is just ferrying computed.

Jakub Holý (HolyJak)19:02:35

Yeah, I read the line but lacked too much background knowledge to understand it.

Jakub Holý (HolyJak)19:02:03

I read about computed properties in the book but still...


Computed props, however, I think I pass through, so you can use (ui-router (comp/computed router {:xxx 1}))


computed is ferried through to the active route


then in the target, just use the 3rd (computed) arg, or (`comp/get-computed this)`

👍 8