Fork me on GitHub

@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.)


[and that's without any devcards complexity]


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 but not sure whether it is the best approach


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).


Here’s the code:


;; 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)))]
             (fn [idx hval] ^{:key idx}
               [:th {:on-click #(reset! sort-key idx)} hval])
               (:headers spec))]]

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


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


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


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


@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]
          (fn [idx hval] ^{:key idx}
            [:th {:on-click #(reset! sort-key idx)} hval])
          (:headers spec))]]

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


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


What I pasted is a form-2 component, you should read about them here:


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


@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.


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


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.


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


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


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


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


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


also i am not making a graphical game


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


hrmm.. they also have their own CES


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


Okay, so more directly answering your question ...


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.


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


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


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.


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


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


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


or i’ve misunderstood something, which is entirely possible


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


The proposal is that this be allowed:

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


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


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


the subscription is no longer at component setup


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


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


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


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


@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..?


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


Sorry, yes, the docs are slightly lagging. The best source of information is currently:


oh that’s useful, thanks