Fork me on GitHub
#reagent
<
2016-10-12
>
johanatan01:10:24

@pesterhazy I get that exception all the time with just figwheel + reagent when the source changes significantly (more than just a style change e.g.)

johanatan01:10:38

[and that's without any devcards complexity]

asier08:10:49

Hi. I need to build a SEO friendly web-app. I'm currently using reagent + re-frame for our web apps. Any advice? I've been looking into this https://yogthos.net/posts/2015-11-24-Serverside-Reagent.html but not sure whether it is the best approach

credulous09:10:07

Hello! I’m trying to do a simple table with sortable columns. I can’t seem to wrap my head around how to manage internal state for the table (i.e. sort column).

credulous09:10:15

Here’s the code:

credulous09:10:19

;; Sortable table component.  Wants to have a data structure
 ;; that looks like this
 ;; { :columns [ :key1 :key2  ]
 ;;   :headers ["Column 1" "Column 2"]
 ;;   :data [ {:key1 "Value 1" :key2 "Value 2"}
 ;;          {:key1 "Value 1" :key2 "Value 2"} ]
 ;; }
 (defn sortable-table [spec]
   (let [sort-key (r/atom 0)
         sort-data (fn [data]
                    (let [k (nth (:columns spec) @sort-key)]
                      (sort #(compare (k %1) (k %2)) data)))]
        [:table
         [:thead
          [:tr
           (map-indexed
             (fn [idx hval] ^{:key idx}
               [:th {:on-click #(reset! sort-key idx)} hval])
               (:headers spec))]]

         [:tbody
          (map-indexed (fn [idx dval ]
            ^{:key idx}
             [:tr
               (map-indexed (fn [colidx c] ^{:key (str idx "-" colidx)} [:td (c dval)]) (:columns spec))])
            (sort-data  (:data spec)))]]))

credulous09:10:50

The table displays correctly, and it sorts by the first column as intended. But when I click a header I get:

credulous09:10:16

In case it’s not clear, it’s #(reset! sort-key idx) that’s causing the error.

credulous09:10:47

I’ve tried #(swap! sort-key inc) just for fun, same result.

reefersleep10:10:47

@credulous: Not that I think that this is causing the error, but when setting up internal state, you need to wrap your inner hiccup structure in an fn just after the let like so:

(defn sortable-table [spec]
  (let [sort-key (r/atom 0)
        sort-data (fn [data]
                    (let [k (nth (:columns spec) @sort-key)]
                      (sort #(compare (k %1) (k %2)) data)))]
    (fn [spec]
      [:table
       [:thead
        [:tr
         (map-indexed
          (fn [idx hval] ^{:key idx}
            [:th {:on-click #(reset! sort-key idx)} hval])
          (:headers spec))]]

       [:tbody
        (map-indexed (fn [idx dval ]
                       ^{:key idx}
                       [:tr
                        (map-indexed (fn [colidx c] ^{:key (str idx "-" colidx)} [:td (c dval)]) (:columns spec))])
                     (sort-data  (:data spec)))]])))

reefersleep10:10:45

Before anything, I would do a hard refresh and see if that sorts out your error 🙂

reefersleep10:10:46

What I pasted is a form-2 component, you should read about them here: https://github.com/Day8/re-frame/wiki/Creating-Reagent-Components

reefersleep13:10:21

@credulous no problem 🙂 Hope you figure out the error. Keep that link at hand, I've referred to it more than once myself 🙂

credulous14:10:15

@reefersleep Actually that solved the problem, thanks! And I now understand the component strategies, and why some reagent components are wrapped in functions. Thanks for the link.

colindresj19:10:01

Do reagent components have access to contexts like React components do?

sandbags22:10:41

I am trying to understand how to model something using re-frame and I wonder if anyone can set me straight. I am building a game and using a component-entity-system to model the data. Let’s take the example of printing the name of the current location of the player. I have a Location component which has a where slot that refers to the entity representing a location. I have a subscription for the player’s location that I use to update a location-name component. All fine except that in that component all I have is the entity (which is an opaque id). I’d need to reach back into the database to get the name component of this entity. But within my component I don’t have a reference to re-frame.db/app-db and I suspect I am not meant to reach in there directly? Then again since I don’t know which entity the location will point at so I can’t setup a subscription for that in advance. I feel like I am missing something here.

sandbags22:10:40

just looking again at the chained reaction example i wonder if i need to setup a chained reaction subscription for the location name component

sandbags22:10:48

my CES data model doesn’t feel like a great fit here

mikethompson22:10:45

@sandbags If CES is central (and I can understand why it would be) I'm wondering if you should be looking at https://github.com/alexkehayias/chocolatier instead of re-frame.

mikethompson22:10:29

I have no direct experience of chocolatier but I've noticed that it has a lot of the same principles.

sandbags22:10:38

@mikethompson i hadn’t come across that, thanks. I love the simplicity of re-frame & re-agent though

sandbags22:10:58

also i am not making a graphical game

sandbags22:10:14

so a lot of the engine stuff they are doing isn’t a benefit

sandbags22:10:50

hrmm.. they also have their own CES

sandbags22:10:17

i’ve no idea if mine is any good in the pantheon of these things

mikethompson22:10:40

Okay, so more directly answering your question ...

mikethompson22:10:15

If you assumed that guarantee was going to be made, you could subscribe to the necessary entities within the view itself, on an as-needed basis.

mikethompson22:10:48

Alternatively ... I'd think about it this way .... the job of a subscription is to deliver to a view the data it needs to render

mikethompson22:10:16

So when you subscribe to a location, that subscription should pull together the necessary entity information so the view can do its job.

mikethompson22:10:35

So pump up your subscriptions and have them deliver the data required. The views should just say (subscribe [:visuals location42]) and have everything they need.

sandbags22:10:29

i guess i would need to use some kind of dynamic subscription for that

sandbags22:10:41

i’m not entirely following that issue as there’s a lot going on in there

sandbags22:10:43

(subscribe [:visuals location42]) wouldn’t work IIRC because I don’t know, until later, that it is location42

sandbags22:10:55

or i’ve misunderstood something, which is entirely possible

mikethompson22:10:55

Just look at the first comment in that #218 issue. It says what is proposed. Ignore the rest.

mikethompson22:10:40

The proposal is that this be allowed:

(defn my-view      ;; Form-1
  []
  [:div  @(subscribe [:a])])))

mikethompson22:10:03

It means that you can subscribe to your entities within the body of the view.

sandbags22:10:04

yes i see that, but i am trying to understand how that changes the situation… it appeared a syntactic simplification

sandbags22:10:31

the subscription is no longer at component setup

sandbags22:10:35

hrmm… i am thinking… so if i had a subscription that watched the player location subscription and then used that to get the entity for the location and it’s components and made that available

sandbags22:10:02

ahhh… i probably should not be trying to think about this so late in the evening, my brain is knotting

sandbags22:10:17

i guess here the two step separation between an entity and its components is always going to make this more tricky, esp. as there may be multiple values of a component for any entity so i have to deal with an intermediate collection

sandbags22:10:25

i guess i will play with chained reactions for a bit and see where that gets me, but i can see the utility of allowing subscriptions in f-1 components

sandbags23:10:27

@mikethompson in the re-frame example docs you have a register-sub returning a reaction but I, and I’m not sure where I modelled this from, am just returning a value but then it looks like reg-sub (I assume the docs are just a little behind) appears to be wrapping things in a reaction via make-reaction anyway..?

sandbags23:10:59

am i going wrong if i subscribe from within a reg-sub?

mikethompson23:10:29

Sorry, yes, the docs are slightly lagging. The best source of information is currently: https://github.com/Day8/re-frame/blob/master/examples/todomvc/src/todomvc/subs.cljs

sandbags23:10:26

oh that’s useful, thanks