# CLJS: Hidden Google Closure Library gems

**URL:** https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321
**Category:** General Questions
**Created:** [June 23, 2018, 6:06pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321 "2018-06-23T18:06:36Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![pesterhazy](https://clojureverse.org/user_avatar/clojureverse.org/pesterhazy/32/395_2.png) [@pesterhazy](https://clojureverse.org/u/pesterhazy)
#### Post date: [June 23, 2018, 6:06pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/1 "2018-06-23T18:06:36Z")

</div>

ClojureScript builds on, and ships with, the Google Closure Library (GCL), a general-purpose JS library of utility functions. The library cover a vast area, from JS data types to various Browser APIs. The [API docs](https://google.github.io/closure-library/api/goog.html) are comprehensive but lack discoverability. So let’s make a list of the most useful functions in this thread.

What are your favorite GCL functions — the library’s hidden gems?

---

<div class="post-metadata">

### Author: ![pesterhazy](https://clojureverse.org/user_avatar/clojureverse.org/pesterhazy/32/395_2.png) [@pesterhazy](https://clojureverse.org/u/pesterhazy)
#### Post date: [June 23, 2018, 6:14pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/2 "2018-06-23T18:14:39Z")

</div>

To get the ball rolling, here’s a first example. `goog.object/get` allows easy js-obj property access by key. It works just like `(clojure.core/get m k)`

```auto
cljs.user=> (goog.object/get #js{"a" 123} "a")
123

```

`(goog.object/get m k)` won’t throw, even if k is not in m or if k or m are nil. You can also supply an optional third argument to specify a default value, if the key is missing.

Next, and similar to `clojure.core/get-in`, `goog.object/getValueByKeys` allows nested property access. Note, however, that unlike `get-in`, it expects each key as a separate argument:

```auto
cljs.user=> (goog.object/getValueByKeys #js{"a" #js{"b" 123}} "a" "b")
123

```

---

<div class="post-metadata">

### Author: ![borkdude](https://clojureverse.org/user_avatar/clojureverse.org/borkdude/32/306_2.png) [@borkdude](https://clojureverse.org/u/borkdude)
#### Post date: [June 24, 2018, 9:59am UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/3 "2018-06-24T09:59:01Z")

</div>

I found the goog.functions namespace worth looking at. E.g. debounce is nice:

[https://google.github.io/closure-library/api/goog.functions.html](https://google.github.io/closure-library/api/goog.functions.html)

I also like goog.string.format.

---

<div class="post-metadata">

### Author: ![ncg](https://clojureverse.org/user_avatar/clojureverse.org/ncg/32/1153_2.png) [@ncg](https://clojureverse.org/u/ncg)
#### Post date: [June 24, 2018, 5:35pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/4 "2018-06-24T17:35:40Z")

</div>

Especially when working with something like React, [goog.async.ConditionalDelay](https://google.github.io/closure-library/api/goog.async.ConditionalDelay.html) is a useful way to wait for dynamic nodes to appear in the DOM. E.g. to scroll a node into view:

```
(defn scroll-to [eid options]
    (let [scroll-fn #(if-some [dom-node (.getElementById js/document (str eid))]
                             (do (.scrollIntoView dom-node options) true)
                             false)]
        (when-not (scroll-fn) (conditional-delay 200 scroll-fn)))))

```

Martin Klepsch also has [a good summary](https://www.martinklepsch.org/posts/simple-debouncing-in-clojurescript.html) on the aforementioned Debouncer.

---

<div class="post-metadata">

### Author: ![shaunlebron](https://clojureverse.org/user_avatar/clojureverse.org/shaunlebron/32/193_2.png) [@shaunlebron](https://clojureverse.org/u/shaunlebron)
#### Post date: [June 25, 2018, 12:46am UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/5 "2018-06-25T00:46:59Z")

</div>

The _Closure Cheat Sheet_ website was a good collection of highlights:

- [closurecheatsheet.com](https://web.archive.org/web/20171207052758/http://www.closurecheatsheet.com:80/) - (via wayback machine)
- [https://github.com/kuzmisin/closurecheatsheet](https://github.com/kuzmisin/closurecheatsheet) (site in markdown)

---

<div class="post-metadata">

### Author: ![pesterhazy](https://clojureverse.org/user_avatar/clojureverse.org/pesterhazy/32/395_2.png) [@pesterhazy](https://clojureverse.org/u/pesterhazy)
#### Post date: [June 25, 2018, 11:29am UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/6 "2018-06-25T11:29:49Z")

</div>

Another useful namespace is goog.crypt. It contains implementations of common hashing algorithms such as MD5 or SHA1. Example usage [here](https://github.com/vimsical/vimsical/blob/0cfd880d4dc7cc6e8ed9d3c6203244115e3d09e8/src/frontend/vimsical/frontend/util/crypt.cljs#L24).

Similarly, the [goog.crypt.base64](https://google.github.io/closure-library/api/goog.crypt.base64.html) namespace contains functions for dealing with Base64-encoded blobs.

---

<div class="post-metadata">

### Author: ![pesterhazy](https://clojureverse.org/user_avatar/clojureverse.org/pesterhazy/32/395_2.png) [@pesterhazy](https://clojureverse.org/u/pesterhazy)
#### Post date: [June 25, 2018, 7:24pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/7 "2018-06-25T19:24:56Z")

</div>

Another fun one: goog.ui.IdGenerator

```auto
cljs.user=> (import 'goog.ui.IdGenerator)
nil
cljs.user=> (def g (goog.ui/IdGenerator.))
#'cljs.user/g
cljs.user=> (.getNextUniqueId g)
":0"
cljs.user=> (.getNextUniqueId g)
":1"
cljs.user=> (.getNextUniqueId g)
":2"

```

---

<div class="post-metadata">

### Author: ![kommen](https://clojureverse.org/user_avatar/clojureverse.org/kommen/32/717_2.png) [@kommen](https://clojureverse.org/u/kommen)
#### Post date: [June 26, 2018, 5:49am UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/8 "2018-06-26T05:49:09Z")

</div>

We found [goog.dom.classlist](https://google.github.io/closure-library/api/goog.dom.classlist.html) to be very handy for manipulating class-strings on dom elements and [goog.positioning](https://google.github.io/closure-library/api/goog.positioning.html) for doing all sorts of positioning and attaching elements like popovers and the like.

---

<div class="post-metadata">

### Author: ![orestis](https://clojureverse.org/user_avatar/clojureverse.org/orestis/32/279_2.png) [@orestis](https://clojureverse.org/u/orestis)
#### Post date: [June 26, 2018, 9:35am UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/9 "2018-06-26T09:35:59Z")

</div>

Positioning looks interesting — how do you use this for popovers etc? Absolutely positioned element appended to the end of the `body`, then figure out what to put on `top, left`?

---

<div class="post-metadata">

### Author: ![dnolen](https://clojureverse.org/user_avatar/clojureverse.org/dnolen/32/504_2.png) [@dnolen](https://clojureverse.org/u/dnolen)
#### Post date: [June 26, 2018, 3:21pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/10 "2018-06-26T15:21:37Z")

</div>

[goog.testing.PseudoRandom](https://google.github.io/closure-library/api/goog.testing.PseudoRandom.html), [goog.labs.userAgent](https://google.github.io/closure-library/api/goog.labs.userAgent.browser.html) are useful

---

<div class="post-metadata">

### Author: ![ordnungswidrig](https://clojureverse.org/user_avatar/clojureverse.org/ordnungswidrig/32/1335_2.png) [@ordnungswidrig](https://clojureverse.org/u/ordnungswidrig)
#### Post date: [June 29, 2018, 6:34pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/11 "2018-06-29T18:34:16Z")

</div>

[goog.Uri](https://google.github.io/closure-library/api/goog.Uri.html) can save you a lot of error prone work.

---

<div class="post-metadata">

### Author: ![pesterhazy](https://clojureverse.org/user_avatar/clojureverse.org/pesterhazy/32/395_2.png) [@pesterhazy](https://clojureverse.org/u/pesterhazy)
#### Post date: [June 30, 2018, 11:04am UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/12 "2018-06-30T11:04:24Z")

</div>

True, and especially `goog.uri.utils/appendParamsFromMap`. The recommendation by @jumblemuddle is what prompted me to start this thread: [CLJS: generate "GET" http request string](https://v2.clojureverse.org/t/cljs-generate-get-http-request-string/2318/3)

---

<div class="post-metadata">

### Author: ![GKlijs](https://clojureverse.org/user_avatar/clojureverse.org/gklijs/32/559_2.png) [@GKlijs](https://clojureverse.org/u/GKlijs)
#### Post date: [June 30, 2018, 12:04pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/13 "2018-06-30T12:04:20Z")

</div>

I tried getting the HTML editor to work, got it half working, but it’s so object oriented.  
Most dom manipulation is easy through.

---

<div class="post-metadata">

### Author: ![ericnormand](https://clojureverse.org/user_avatar/clojureverse.org/ericnormand/32/1099_2.png) [@ericnormand](https://clojureverse.org/u/ericnormand)
#### Post date: [July 16, 2018, 7:02pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/14 "2018-07-16T19:02:14Z")

</div>

This is a great list! I didn’t know most of this stuff.

I like [History](https://google.github.io/closure-library/api/goog.History.html) and [Html5History](https://google.github.io/closure-library/api/goog.history.Html5History.html)

They have the same API, so you can use Html5History with a fallback to History.

Eric

---

<div class="post-metadata">

### Author: ![jjttjj](https://clojureverse.org/user_avatar/clojureverse.org/jjttjj/32/2926_2.png) [@jjttjj](https://clojureverse.org/u/jjttjj)
#### Post date: [July 21, 2018, 4:03pm UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/15 "2018-07-21T16:03:58Z")

</div>

I used this the other day:

```auto
... 
(:import (goog.i18n NumberFormat)
         (goog.i18n.NumberFormat Format))
...

```

```auto
(def formatter (NumberFormat. Format/COMPACT_LONG))
(.format formatter 4356555555) ;;=> "4.4 billion"
(.format (NumberFormat. Format/COMPACT_SHORT) 4356555555) ;;=> "4.4B"

```

I believe there are a lot of i18n options for this as well.

---

<div class="post-metadata">

### Author: ![system](https://clojureverse.org/uploads/default/original/2X/5/51079bf9e4b7d9466242c06cf1e43b9f8bd6da14.png) [@system](https://clojureverse.org/u/system)
#### Post date: [January 20, 2019, 4:04am UTC](https://clojureverse.org/t/cljs-hidden-google-closure-library-gems/2321/16 "2019-01-20T04:04:03Z")

</div>

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.
