fulcro

Book: http://book.fulcrologic.com, Community Resources: https://fulcro-community.github.io/, RAD book at http://book.fulcrologic.com/RAD.html
tvaughan 2020-11-08T12:01:09.080100Z

I have a component that uses a state machine to trigger a remote mutation on button click. The result of this mutation is in another component. How do I pass this back to the originating component? I tried making the downstream component a part of the originating component, and I tried adding a field to the originating component and updating that by swapping on the state atom directly in the state machine’s ok event, neither seem to work. What am I doing wrong, again?

xceno 2020-11-09T11:07:16.081400Z

Your last part seems okay though, can you share some code? Also, is ComponentA included all the way up to your root component?

tvaughan 2020-11-09T11:20:35.081600Z

This is the Session component:

(defsc Session
  [this {:keys [session/token session/current-user session/error] :as props}]
  {:query [:session/token :session/current-user :session/error]
   :ident (fn [] [:component/id :session])
   :initial-state {}}
  (when token
    (dom/div (:current-user/email-addr current-user))))
I want to be able to "use" :session/error in another component, Component A. Component A isn't anything special. It is routable. Neither component is included all the way up to the root. I haven't tried that, yet. I can see in the inspector that the data I expect is indeed in the Session component. It's a singleton. I know it's ident. However, I can't figure out how to make use of it within Component A

xceno 2020-11-09T11:26:11.081800Z

So if I understand correctly your mutation is directly modifying Session and you wan't ComponentA to react on it(?). But I think you should turn it around. Your mutation needs to update the data in ComponentA's edge to Session and then ComponentA will get the updated properties and can pass it down to Session. At least that's how I've always done it. So your state map might look like

{:component/id ::ComponentA {:session-props {...}}}
But let me try something real quick

xceno 2020-11-09T11:26:44.082Z

(It's my first fulcro project, so I'm still learning a lot)

tvaughan 2020-11-09T11:27:43.082200Z

I rather naively tried:

(defsc ComponentA
-  [this {:keys [component/id email/addr user/password] :as props}]
-  {:query [:component/id :email/addr :user/password form-state/form-config-join]
+  [this {:keys [component/id email/addr user/password sessions/session] :as props}]
+  {:query [:component/id :email/addr :user/password {:sessions/session (get-query Session)} form-state/form-config-join]
@@ -372,6 +372,7 @@
+                    (dom/h1 (:session/error session))

tvaughan 2020-11-09T11:27:56.082400Z

Appreciate the help @rob703!

tvaughan 2020-11-09T11:30:24.082600Z

The state machine looks like:

(defstatemachine session-machine
  {::uism/actor-names
   #{:actor/session-token
     :actor/create-session
     :actor/delete-session}

   ::uism/states
   {:initial
    {::uism/handler
     handle-check-session!}

    :state/post-check-session
    {::uism/events
     (merge session-events
            {:event/check-session-ok
             {::uism/handler
              (fn [{:keys [::uism/app ::uism/state-map] :as env}]
                (if-let [error (get-in state-map [:component/id :session :session/error])]
                  (io/pprint {:session/error error}))
                (when (get-in state-map [:component/id :session :session/token])
                  (hist/route-to! routes/default-route))
                env)}
             :event/check-session-error
             {::uism/handler
              (fn [env]
                (io/pprint {:check-session-error env})
                env)}})}

tvaughan 2020-11-09T11:30:51.082800Z

The Session component is the actor for session-token, and ComponentA is the actor for create-session

xceno 2020-11-09T11:35:26.083Z

Ah yes, I'd swap the session state on :component/id ::ComponentA :sessions/session and then pass it along to to your session component

tvaughan 2020-11-09T11:42:57.083200Z

Sorry, I don't quite understand 😞

xceno 2020-11-09T11:43:17.083400Z

I'm just writing an example, hang in there

tvaughan 2020-11-09T11:44:30.083600Z

The Session component, I'm hoping, can just represent the session state, and not be required to render anything. While, ComponentA, for example, renders a signin form and triggers a remote mutation to create the session

xceno 2020-11-09T11:46:37.083800Z

Ah I missed that part, sorry. Yes it doesn't have to render anything. In that case you may want to look at the RAD demos auth system. It isn't fully fleshed out, but it's a start

xceno 2020-11-09T11:47:21.084300Z

I think you're trying to do exactly the same

tvaughan 2020-11-09T11:50:53.084500Z

> I think you're trying to do exactly the same Thanks. At least I know I'm not going off in some wildly ridiculous direction πŸ™‚ I'll try attaching things to the Root component Thanks!

xceno 2020-11-09T11:54:41.084700Z

What's happening here is that the ui-authenticator on line #105 renders the login form for you. That's configured here: https://github.com/fulcrologic/fulcro-rad-demo/blob/master/src/shared/com/example/client.cljs#L43 And as you can see you still need to include your session component somwhere in your UI tree and pass it the props. So the {:authenticator (comp/get-query Authenticator)} in the RAD demo is the "edge" I was speaking of earlier. Hope that helps a bit, sorry for having a slow brain today haha πŸ™‚

tvaughan 2020-11-09T11:57:41.085100Z

> Hope that helps a bit, sorry for having a slow brain today haha I really appreciate you taking the time to help me with this! I'm not using RAD, but I'll look though these pointers to see what I can learn

tvaughan 2020-11-09T12:53:03.085300Z

Looking at this now http://book.fulcrologic.com/#_link_queries

xceno 2020-11-09T12:57:15.085500Z

Ah true, I forgot about this! I'm using it myself to pull in stuff like global options for dropdowns n stuff

xceno 2020-11-09T12:59:59.085700Z

The follow up is quite important: > http://book.fulcrologic.com/#_a_warning_about_ident_and_link_queries This one bit me the first time

tvaughan 2020-11-09T13:04:07.085900Z

(defsc ComponentA
  [this {:keys [component/id email/addr user/password sessions/session] :as props}]
  {:query [:component/id :email/addr :user/password {[:sessions/session '_] (get-query Session)} form-state/form-config-join]

tvaughan 2020-11-09T13:04:16.086100Z

This is working

xceno 2020-11-09T13:05:21.086300Z

Nice, glad you figured it out!

tvaughan 2020-11-09T13:05:47.086500Z

Thanks again for your help, @rob703!

tvaughan 2020-11-08T12:13:40.080200Z

Component "A" has :onClick #(uism/trigger! this :sessions/session :event/create-session! {...}) mutates a Session component. Component A needs to react to changes in the Session component

tvaughan 2020-11-08T12:15:38.080400Z

I've made the Session component a part of Component A's props and query, and invented a duplicate prop in Component A and tried to update that via the state map. Both seemed to do nothing 😞