Fork me on GitHub
#fulcro
<
2019-10-18
>
rsslldnphy12:10:56

hi, have just started working on a project written in fulcro, trying to get my head round it. have a question that feels like it’s probably very basic but i can’t work it out. i want to conditionally include one of two child components in a parent component based on some data in the component. however as the parent needs to include the correct query/initial state for the child, i’m not sure how to achieve this. what pattern should i be using for this kind of case?

rsslldnphy12:10:23

here’s some code to illustrate what i mean (it doesn’t compile, just to give you an idea of what i’m talking about)

rsslldnphy12:10:29

;; assume the heaven and hell components are different, with different queries etc - they're just basic ones here for illustrative purposes
(defsc Hell [this {:keys [name]}]
  {:query [:name]
   :initial-state {:name "hell"}}
  (dom/div (dom/p "welcome to " name)))

(def ui-hell (prim/factory Hell))

(defsc Heaven [this {:keys [name]}]
  {:query [:name]
   :initial-state {:name "heaven"}}
  (dom/div (dom/p "welcome to " name)))

(def ui-heaven (prim/factory Heaven))

(defsc ConditionalComponent [this {:keys [place good?]}]
  {:query [:good? {:place (if good? ;; this doesn't work as `good?` is not accessible
                            (prim/get-query Heaven)
                            (prim/get-query Hell))}]
   :initial-state (fn [_] {:good? false
                           :place (if good?  ;; this doesn't work as `good?` is not accessible
                            (prim/get-initial-state Heaven {})
                            (prim/get-initial-state Hell {}))})}
  (dom/div
    (if good?
      (ui-heaven place)
      (ui-hell place))
    (dom/p (str "Are we in the good place? " good?))))

(def ui-conditional-component (prim/factory ConditionalComponent))

(defsc Root [this {:keys [choice]}]
  {:query         [{:choice (prim/get-query ConditionalComponent)}]
   :initial-state (fn [_] {:choice (prim/get-initial-state ConditionalComponent {})})}
  (dom/div
    (ui-conditional-component choice)
    (dom/button {:onClick #(prim/transact! this `[(toggle-good)])} "Click here")))

(defmutation toggle-good
  [params]
  (action [{:keys [state]}] (swap! state update-in [:choice :good?] not)))

rsslldnphy12:10:45

i’ve got it “working” like this:

rsslldnphy12:10:48

(defsc ConditionalComponent [this {:keys [heaven hell good?]}]
  {:query [:good?
           {:heaven (prim/get-query Heaven)}
           {:hell (prim/get-query Hell)}]
   :initial-state (fn [_] {:good? false
                           :heaven (prim/get-initial-state Heaven {})
                           :hell (prim/get-initial-state Hell {})})}
  (dom/div
    (if good?
      (ui-heaven heaven)
      (ui-hell hell))
    (dom/p (str "Are we in the good place? " good?))))

rsslldnphy12:10:18

but won’t that cause initial state and queries to be included in the parent component regardless of whether the component is ever rendered? is that expected or is there a way round it?

tony.kay15:10:58

You’re looking for Union queries

tony.kay15:10:40

In book, and in this F2 (unpublished) video:

tony.kay15:10:11

NOTE: The video is outdated (fulcro 2.x), so the requires are in the wrong place…but everything content wise is otherwise correct.

tony.kay15:10:54

You can also use dynamic queries, but they are more advanced….If you’re really a beginning, probably better just to include both in the query to start and refine that later as an optimization.

rsslldnphy15:10:46

thanks - this project uses fulcro 2 so the video will be ideal

tony.kay15:10:42

I re-listed the 2.x videos so you can find them more easily…was trying to reduce confusion, but they are clearly labeled, so it should be ok

henrik13:10:24

I’m trying to rig up https://wilkerlucio.github.io/pathom/#GraphQL (while adapting it to run on the backend). Is there any way to inject some headers to the HTTP driver for load-index? Looking at the source, it seems interested in the URL and the URL alone.

tony.kay15:10:23

Fulcro client: Use middleware in http-remote (see docs) Fulcro server: It’s just Ring Otherwise: Use the source

👍 4
tony.kay15:10:52

Perhaps also ask in #pathom

Chris O’Donnell11:10:27

@U06B8J0AJ If you haven't figured it out already, you can do it like this:

(pcg/load-index (assoc-in my-gql
                          [::p.http/headers :authorization]
                          (str "Bearer " (:id-token @auth/auth)))
                indexes)

👍 4
henrik09:10:30

Thanks! @U0DUNNKT2 I had improperly formatted the headers, then misread the source. Now it works! (kinda)

tony.kay18:10:24

@mdhaney any tips on getting the native base default theme to look right?

tony.kay18:10:42

their eject instructions eject stuff that would have to pre processed into “plain” js

mdhaney18:10:31

I just override the styling on individual components. Most of their components like form controls, action sheets, etc. I use the default styling so it looks right on both platforms (that’s why I’m using NB in the first place). The main stuff I needed to customize was header and tabbed footer, changing color, font, etc.

tony.kay18:10:40

I’m getting blue buttons with black text (hideous..unbelievable default)

mdhaney18:10:56

Whoa, that’s weird.

mdhaney18:10:15

Can you share a gist or something?

tony.kay18:10:33

nothing special…

tony.kay18:10:46

just using Button from native-base within container

tony.kay18:10:34

container/content/button

tony.kay18:10:57

and using the stuff we wrote for fulcro-native

mdhaney18:10:57

Hmmm, that should work.