0

Trying to use antd from clojurescript I'm looking for an idiomatic way to destructure js-objects. So assume we want to do e.g.

import { Layout } from 'antd';

const { Header, Footer, Sider, Content } = Layout;

How can I do that from clojurescript without having to write the verbose

(let [Sider (.-Sider antd/Layout)
            Header (.-Header antd/Layout)
            Content (.-Content antd/Layout)
            Footer (.-Footer antd/Layout)]
  ;; and here goes the hiccup using Sider etc.
)

thanks in advance

fricke

fricke
  • 1,330
  • 1
  • 11
  • 21
  • Not a real answer but `antd/Layout.Header` would be ok to use. Don't need to assign it extra if you are only going to use it once anyways. – Thomas Heller Oct 08 '19 at 13:13
  • thx, this is true in most cases - but when I bumped into this question, I realised that I have no clue how to destructure js-objects (if it is possible at all) – fricke Oct 08 '19 at 13:57
  • Can you just use `(js->clj Layout)` and then use normal Clojure destructuring? – Alan Thompson Oct 08 '19 at 16:39
  • unfortunately, this does not work - was my first guess, too – fricke Oct 08 '19 at 17:35
  • 1
    Don't ever use `js->clj` for cases such as this. `js->clj` is reserved for data. This is code, it may have circular references. – Thomas Heller Oct 08 '19 at 19:07

2 Answers2

0

The useful forms of destructuring (:keys, :strs) won't work because a regular JS object is not a CLJS map. Maybe you can create an util function around aget and use regular positional destructuring?

(defn obj-props [obj props]
  (map #(aget obj (name %)) props))

(let [[Sider Header Content Footer] (obj-props antd/Layout '[Sider Header Content Footer])]
 ;; Sider, Header, etc. are bound here
 )

I found a recommendation on the Cljs Cheat Sheet of the cljs-oops library, which in turn mentioned aget, and the aget docs mentioned goog.object/get

Denis Fuenzalida
  • 3,271
  • 1
  • 17
  • 22
  • 1
    Before using tricks like these please consider the performance implications. `antd/Layout.Header` is bascically free. This isn't. – Thomas Heller Oct 09 '19 at 09:00
  • actually this works - it's not as simple as one might like it - so thanks a lot But I guess I'll stick with the verbose solutions for now – fricke Oct 09 '19 at 09:31
0

Here's how i currently prefer to do it:

(let [[Sider Header Content Footer]
      (as-> antd/Layout $ [(.-Sider $) (.-Header $) (.-Content $) (.-Footer $)])]
;; and here goes the hiccup using Sider etc.
)

Or else:

(let [[Sider Header Content Footer]
      ((juxt #(.-Sider %) #(.-Header %) #(.-Content %) #(.-Footer %)) antd/Layout)]
;; and here goes the hiccup using Sider etc.
)
  • these are much nicer (I prefer the first over the second) - still more repetition than a proper destructuring but much better than before – fricke Oct 11 '19 at 18:17