I try to write this d3.js's code https://bl.ocks.org/d3noob/43a860bc0024792f8803bba8ca0d5ecd with clojurescript because I want to use re-frame framework.
But I could not find any solution because it has the process of changing values in a dictionary such as the function #'collapse.
I have a problem. Can ClojureScript write changing values in a dictionary?
ex.
function remove_children (d) {
if (d.children) {
d.children = null;
}
}
family_tree = {
name: "John",
children: [
{ name: "Jack",
children: [
{ name: "Michel"}]},
{ name: "Emily",
children: [
{ name: "Mike"}]}]
};
jack = family_tree.children[0]
remove_children(jack)
;; in clojurescript ... I have no solution ...
As mentioned above, you might run into issues later if you are trying to work with mutable data (for D3) and immutable data (for re-frame).
When possible, use ClojureScript's own data structures and only pass JavaScript objects when iteracting with libraries, eg. you can use (clj->js my-map)
to convert a CLJS map into a JS object.
If you want to use JS interop to mutate JavaScript objects, that's also possible:
(def family-tree
(clj->js
{
"name" "John",
"children" [
{ "name" "Jack",
"children" [
{ "name" "Michel"}]},
{ "name" "Emily",
"children" [
{ "name" "Mike"}]}]
}))
;; Check if family-tree looks like expected:
cljs.user=> family-tree
#js {:name "John",
:children #js [#js {:name "Jack",
:children #js [#js {:name "Michel"}]}
#js {:name "Emily",
:children #js [#js {:name "Mike"}]}]}
;; Define remove-children and Jack using interop:
(defn remove-children [elem]
(set! (.-children elem) nil))
(def jack
(-> family-tree .-children (get 0)))
;; Test them
cljs.user=> (remove-children jack)
nil
cljs.user=> family-tree
#js {:name "John",
:children #js [#js {:name "Jack", :children nil} ;; <== Children were deleted
#js {:name "Emily",
:children #js [#js {:name "Mike"}]}]}