Fork me on GitHub
#reagent
<
2020-04-10
>
Pavel Klavík02:04:54

Hi, I am getting a strange error while trying to wrap Table from Material-ui. My code works as follows:

(defn head
  "Renders the table head."
  [columns]
  [:> TableHead
   [:> TableRow
    (for [{:column/keys [id align label]} columns]
      [(r/adapt-react-class TableCell) {:key   id
                                        :align (when align (name align))}
       label])]])

(defn body
  "Renders the table body."
  [rows columns]
  [:> TableBody
   (for [{:row/keys [data] :as row} rows]
     [(r/adapt-react-class TableRow) {:key (:row/id row)}
      (for [{:column/keys [id align]} columns]
        [(r/adapt-react-class TableCell) {:key   id
                                          :align (when align (name align))}
         (get data id)])])])

(defn table
  "Renders a table described by a map."
  [{:table/keys [columns rows class style]}]
  [:> TableContainer {:component Paper}
   [:> Table {:class class
              :style style}
    [head columns]
    [body rows columns]]])
and it should be used like this
[table/table #:table{:columns [#:column{:id :a
                                        :label "A"}
                               #:column{:id :b
                                        :label "B"}]
                     :rows [#:row{:id :row1
                                  :data {:a "XYZ"
                                         :b "CDE"}}
                            #:row{:id :row2
                                  :data {:a "XYZ2"
                                         :b "CDE2"}}
                            #:row{:id :row3
                                  :data {:a "XYZ3"
                                         :b "CDE3"}}]}]
But I am getting error:
Uncaught Error: Material-UI: capitalize(string) expects a string argument.
    at exports.default (capitalize.js:16)
    at TableCell.js:181
    at renderWithHooks (react-dom.development.js:14826)
    at updateForwardRef (react-dom.development.js:16841)
    at beginWork (react-dom.development.js:18679)
    at HTMLUnknownElement.callCallback (react-dom.development.js:189)
    at Object.invokeGuardedCallbackImpl (react-dom.development.js:238)
    at invokeGuardedCallback (react-dom.development.js:293)
    at beginWork$1 (react-dom.development.js:23235)
    at performUnitOfWork (react-dom.development.js:22186)
When just using the component directly, everything works fine:
[:> TableContainer {:component Paper}
 [:> Table
  [:> TableHead
   [:> TableRow
    [:> TableCell "A"]
    [:> TableCell "B"]]]
  [:> TableBody
   [:> TableRow
    [:> TableCell "XYZ"]
    [:> TableCell "CDEF"]]]
  [:> TableBody
   [:> TableRow
    [:> TableCell "XYZ2"]
    [:> TableCell "CDEF2"]]]
  [:> TableBody
   [:> TableRow
    [:> TableCell "XYZ3"]
    [:> TableCell "CDEF3"]]]]]

David Pham10:04:12

Why do you wrap TableRow and TableCell in adapt react class? In your head and body? Did you try to only display head? An issue might be the interop because material ui convert keywords into string.

Pavel Klavík11:04:47

I took a more careful look into the code and I have figured it out. The problem is that nil is not ignored in JS, so

(when align (name align))
creates a nil when align is missing. But I need to remove the key completely.

David Pham12:04:29

Good things to know!