1

I have a dead simple ClojureScript/Om application. It seems a little broken.

This is the core file:

(ns demo.core
  (:require-macros [cljs.core.async.macros :refer [go]])
  (:require [goog.events :as events]
            [cljs.core.async :as async :refer [>! <! put! chan]]
            [om.core :as om :include-macros true]
            [om.dom :as dom :include-macros true]
            [goog.events.EventType :as EventType]
            [clojure.string :as string]))

(defn layout
  [app owner]
  (reify
    om/IRender
    (render [_]
      (dom/div {:id "some-id"} "Pumpkin"))))

(defn main []
  (om/root
    layout
    {}
    {:target (. js/document (getElementById "app"))}))

It renders this HTML:

<div id="app">
    <div data-reactid=".0">Pumpkin</div>
</div>

Why doesn't the div have the id #some-id?

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
Sir Robert
  • 4,686
  • 7
  • 41
  • 57

1 Answers1

4

You need to use the #js {} reader literal to specify a JS object rather than a plain-old map:

(dom/div #js {:id "some-id"} "Pumpkin")

This is elaborated a bit in the Om Tutorial.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
  • Ok, I buy that... but how do I set arbitrary, non-js attributes? I have some code from another project that doesn't need #js to work and can use {:class "foo"} instead of {:className "foo"} and it seems fine. Apparently I don't understand what's happening well enough to see the distinction. Any tips? – Sir Robert Feb 03 '15 at 02:11
  • @SirRobert You’re not setting a “JS attribute”. `#js {}` just creates a JavaScript object rather than a Clojure(Script) map; this is [part of ClojureScript](http://dev.clojure.org/jira/browse/CLJS-717), not Om. This is needed because this is passes straight into React, which only understands JS objects, not CLJS maps. You can read about [React’s supported DOM attributes](https://facebook.github.io/react/docs/tags-and-attributes.html#html-attributes) for more info. – Andrew Marshall Feb 03 '15 at 02:31
  • @SirRobert That said, I’m not sure why `{:class "foo"}` worked in your other project. It’s possible either that Om handles/handled that specially (I haven’t tested this), or that an [alternate DOM syntax](https://github.com/omcljs/om#can-i-use-a-different-html-syntax) was being used. – Andrew Marshall Feb 03 '15 at 02:35
  • 2
    I see what was going on. In the other project, they were using [om-tools.dom :as dom] rather than [om.dom :as dom]. Apparently om-tools provides some sugar for that kind of thing (https://github.com/Prismatic/om-tools#dom-tools). – Sir Robert Feb 03 '15 at 03:22