re-frame 2023-10-18

Question to everyone: How do you prevent yourself and your collaborators from accidentally reusing state paths? Maybe the question can be rephrased more generally: how to you organize the overall application state so that you don't accidentally reuse paths, and maybe conversely so that you can discover paths that would be sensible to reuse?

Common storage for common data. Namespaced or composite keys for the rest. Discovery via documented functions that wrap usage of those keys.

Just to expand; is your common data then not namespaced?

Only the entry point key is namespaced.

Ah. So you have paths like [:common/data :user-name] ?

Something like that.

Thanks 🙂 I asked the question expecting answers like that, and it's great to hear it confirmed. Always dig your input, @p-himik

👍 1

We build up conventions around this as well.

Related data shares related prefix in a predictable way so that can help with “discovery”. That said, when things get big enough, “discovery” of what already exists can be tricky still.

This is a general issue in our code base. Soooo much stuff to know about.

👍 2

If you solve it. Let me know the secret. 🤣

🫡 1

AgGridReact need for help 😞 I want to use ag-grid (https://www.ag-grid.com/react-data-grid/) in my web-app according to https://day8.github.io/re-frame/Using-Stateful-JS-Components/ I have below code (which works - displays ag-grid on a page)

(defn data-grid-inner []
      (let [ref (react/useRef)]
           (r/create-class
             {:display-name "ag-grid"
              :reagent-render
              (fn []
                  [:div {:className :ag-theme-alpine
                         :style     {:height 500}}
                   [c/ag-grid
                    {:ref           ref
                     :defaultColDef {:type             :numericColumn
                                     :sortable         false
                                     :cellEditorParams {:showStepperButtons true}}}]])

              :component-did-mount
              (fn [comp]
                  (let [[_ rows columns] (r/argv comp)]
                       (log/debug :api-update (.. ref -current -api))
                       #_(.setColumnDefs @api columns)))

              #_#_:component-did-update update})))

(defn data-grid-outer []
      (let [rows @(rf/subscribe [:table/rows :trajectory/points])]
           (fn [] [:f> data-grid-inner rows columns])))
but the problematic line is
(log/debug :api-update (.. ref -current -api))
it shows undefined (screenshot attached) but when I remove -api ->
(log/debug :api-update (.. ref -current))
it looks ok (screenshot): I looked for solution on Slack and Google, tried different forms of interop (^js, #js, goog.object, oops. threading macros, dotdot) Could you help me, please?

@jahson - I tried, failed, but finally I removed AgGridReact in favour of vanilla JS and now it looks like that:

...
[reagent.core :as r]
["ag-grid-community" :as ag]
...

(defn- data-grid-inner []
       (let [data-grid (atom nil)
             update #(let [[_ cols rows] (r/argv %)
                           api (.. @data-grid -gridOptions -api)]
                          (.setColumnDefs api (clj->js cols))
                          (.setRowData api (clj->js rows)))]
            (r/create-class
              {:display-name         "data-grid"
               :reagent-render       #(vector :div {:id        "data-grid"
                                                    :className :ag-theme-alpine
                                                    :style     {:height 350}})

               :component-did-mount  #(do (reset! data-grid
                                                  (ag/Grid. (.getElementById js/document "data-grid") {}))
                                          (update %))
               :component-did-update update})))

(defn data-grid [columns rows]
      [data-grid-inner columns @rows])

...
(def columns [{...} ... {...}])
...

...
[data-grid columns (rf/subscribe [rows points])]
...

With using ag-grid react component and error like "Uncaught Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement in React Hooks"

It might be related to the fact that log shows not the state of object at the moment of logging: https://developer.mozilla.org/en-US/docs/Web/API/console/log#logging_objects

@jahson - I've uncomment and change line below to: (.setColumnDefs (.. ref -current -api) columns) and it gives: Cannot read properties of undefined (reading 'setColumnDefs')

It happens because there is no api property when you do this.

(log/debug :api-update (.. ref -current -columnApi))
also gives undefined , but, i.e.:
(log/debug :api-update (.. ref -current -props))
returns the actual value

Could you please provide me with require for ag-grid and the way you’ve used r/adapt-react-class on AgGrid?

This way I will be able to reproduce it faster.

["ag-grid-react" :as ag]
(def ag-grid (r/adapt-react-class ag/AgGridReact))

After trying to reproduce and fast search it looks an issue with documentation. I’ve seen a few mentions of onGridReady.

It seems like the easiest possible way is to use :onGridReady and store a reference to API in atom.

@jahson - Many, many, many thanks! I will check your advises

👍 1