Fork me on GitHub
#re-frame
<
2018-12-31
>
andrea.crotti11:12:40

ah yes conduit is quite nice, I was looking at that as well to understand how to use Pushy

andrea.crotti11:12:18

and looking at

(case page
                ;; -- URL @ "/" --------------------------------------------------------
                :home {:db set-page
                       :dispatch-n  (list (if (empty? (:user db))             ;; dispatch more than one event. When a user
                                            [:get-articles {:limit 10}]       ;; is NOT logged in we display all articles
                                            [:get-feed-articles {:limit 10}]) ;; otherwiser we get her/his feed articles
                                          [:get-tags])}                       ;; we also can't forget to get tags
in that project made me think, is it wrong then to trigger (rf/dispatch [::handlers/load-data]) in my view directly in the root component?

andrea.crotti11:12:13

I guess it's probably not great, and I constantly forget to do it the first time, probably the view should not know at all how to load the needed data

hoopes20:12:49

Is it right (or weird/wrong/etc) to only hold raw, simple data in the app db? I'm considering using mount for a websocket connection - it feels strange to me to put things like websocket connections in the app db. I was also considering using https://github.com/oliyh/martian/tree/master/re-frame for a couple different external APIs, which holds a JS object in the app db as well, which made me kinda want to make that a mount component instead. Things that could be rebuilt/reconnected and are not explicitly data that drives the app feel like outside of the app db is the place to be, but I thought I'd ask the experts.

mikethompson20:12:54

@andrea.crotti The question you are asking is: "is it okay to make views imperative" and my answer is "Avoid that.". To the greatest extent possible, try to make views simply be a reactive rendering of application state and that's all. The event hander should "know" what data should be loaded (and perhaps what existing subscriptions to cancel, etc). Having said that, the React world has trained a LOT of developers to "drive" their applications off the view, so these days I get a fair bit of pushback on this opinion. ALSO, I'm not a fan of the approach taken in that Pushy code fragment you supplied. For the :home case, I believe there should be a single [:dispatch :navigate-home] and ALL the logic for that "user intent" should be in the associated event handler itself. We want all the logic in event handlers. AND also I don't like an event dispatch to be like a function call. An event should capture "user intent" like "I want to navigate to the home page" and not have a system's perspective like "load this data" or "load that data". The loading of data is "an effect" of the event. An effect of the user intent and should not be modeled as an event.

lilactown21:12:32

not meaning to hijack a a convo I’m not involved in, but I do think that one of the good reasons that the React world tends to use construction/on-mount to load data is because components are the primary method of composition

lilactown21:12:25

if you have a component that yesterday was static, but today needs data, right now you have to do a bunch of out-of-band work (w.r.t. the component tree) to ensure that component has what it needs to render appropriately

lilactown21:12:08

it’s tenable when all the code is your own, but creating lib components meant to be consumed by other applications and consuming 3rd party libs is where the rubber meets the road in terms of composability

lilactown21:12:13

fundamentally, I think that mainstream React is moving towards a true “component-oriented” architectural model which is at odds with the “just the view” thinking that has dominated

mikethompson21:12:19

@hoopes to the greatest extent possible, I would NOT put a websocket connection in app-db. I tend to want only Clojure data in app-db. The websocket stuff can be held off to one side. Arriving messages of interest should be dispatched. Websockets themselves should be established and torn down via `effects.

hoopes21:12:22

i kinda like mount 🙂 even if it does make those "external" things kinda global

mikethompson21:12:39

So I would want to treat websockets as "external" to the app. An agent that creates dispatch-able events, the same way that the user creates events via the mouse.

hoopes21:12:04

yeah, i'm glad you said that, it felt weird to put big objects in the db that couldn't be serialized if i wanted to

hoopes21:12:24

i have a hope of "oh no, something happened, the exception handler serializes the app db as part of the reported exception"

hoopes21:12:31

which wouldn't really work with a websocket conn in there

mikethompson21:12:37

You might be interested in re-frame-async-flow

hoopes21:12:48

yes, yes i am

hoopes21:12:54

(in place of mount, you mean?)

hoopes21:12:10

i was using that for other boot-related stuff

hoopes21:12:34

i will give it a shot, thanks. happy new year!

mikethompson21:12:51

Yes, you too. Happy new year.

WhoNeedszZz22:12:22

Hey, folks. Just learning re-frame for a simple informational site. I'm using Material-UI for my styling and having some difficulty with styles being overridden by duplicate elements being created. Specifically, when I'm using the Grid component it will create an element that I stated with the options I stated, but will create another one above it that has the default Material-UI style options. Why is this happening and how do I stop it from creating the duplicate elements?

WhoNeedszZz22:12:18

Even stranger is that the top-most parent correctly creates the <WithStyles(Grid) ... > with the options I stated and a child of <Grid ...> with the options I stated. It's further down the tree that it flips around where it is a <Grid ...> with default options that overrides the <WithStyles(Grid) ...>.

Kelly Innes22:12:35

Can you try to re-create the same bug but in a non-re-frame-attached Reagent function?

Kelly Innes22:12:55

I vaguely remember just reading something about Reagent and MaterialUI, so it might be related to that. Let me see if I can find it.

Kelly Innes22:12:32

It seems like you might need to be doing r/reactify-component and r/adapt-react-class to get the functions to pass back and forth between being Reagent and React components?

WhoNeedszZz22:12:08

I'm using [:<>] and [:>] for that

Kelly Innes22:12:18

Oh, okay! I don't even know what those are yet!

WhoNeedszZz22:12:50

They're convenience functions for fragments and reactifying

Kelly Innes22:12:15

Do you know whether the bug exists in the Material UI React library? In the sense of it being reported on their GitHub repo.

WhoNeedszZz22:12:37

(defn home-content []
  (let [name (re-frame/subscribe [::subs/name])]
    [:<>
     [:> Grid
      {:container true
       :direction "row"
       :justify "center"
       :spacing 8}
      [:> Grid
       {:container true
        :direction "row"
        :justify "center"
        :xs 12}
       [:> Grid
        {:item true
         :xs 12}
        [appbar-comp]]]
      [:> Grid
       {:container true
        :direction "row"
        :justify "center"
        :spacing 8
        :xs 12}
       [:> Grid
        {:item true
         :xs 6}
        [:> Card
         {:style style-card}
         [:> CardMedia
          {:image "../../resources/public/images/logo-300_240.png"}]
         [:> CardContent
          [:> Typography
           {:component "p"}
           "Test"]]]]
       [:> Grid
        {:item true
         :xs 6}
        [:> Card
         {:style style-card}
         [:> CardContent
          [:> Typography
           {:component "p"}
           (str "Hello from " @name ". This is the Home Page.")]]]]]]]))

Kelly Innes22:12:47

I remember working with some buggy React libraries that would mount things incorrectly, then lose track of them and think they'd need to re-create.

WhoNeedszZz22:12:53

Does Slack not understand clojure syntax?

WhoNeedszZz22:12:15

So I am creating a container of two containers, with the first container only containing the app bar and the second container containing the cards. That's how it is documented on the Material-UI docs so I don't know where the issue is.

mikethompson23:12:43

@whoneedszzz For a bigger audience, I'd ask this question across on the #reagent channel