0
votes

This is a piece of code for a Chrome extension.

I am starting with ClojureScript, so this might be some trivial problem, and though I have found the solution, I still don't understand why the problem happens.

This is the piece of code that grinds my gears:

(defn print-and-save-selection
  [info tab]
  (let [selection-text (.-selectionText info)]
    (println info) ;; => #js { bunch of properties, "selectionText" being one }
    (.get js/chrome.storage.sync
          (clj->js {:history nil :historyItems []})
          (fn [items]
            (println items)  ;; => #js {:history nil :historyItems #js []}
            (let [history-items (.-historyItems items)
                  updated-history-items (.concat history-items selection-text)]
              (println updated-history-items)  ;; => correct list in :whitespace mode
              ;; save stuff using other chrome.storage function

I have my externs properly set and this code works correctly under :whitespace optimiziations, but not under :advanced. For the latter, it gaves me a "Cannot read property 'concat' of undefined". In other words, (.-historyItems) fails to find the appropriate element inside items. If I change this to (aget items "historyItems") it works, even in :advanced.

What I can't understand is why the functionality that works for (.-selectionText info) (third line) does not work for (.-historyItems items), when both of them are accessing a property of a JavaScript object. This might be related to the level of nestedness of this code?

For completeness, the generated code is something like this:

:advanced without aget

var a = b.selectionText;
...
// a few nested returns and functions ...
    var h = g.Ab, c = h.concat(a);  // => error mentioned above

:advanced with aget

var a = b.selectionText;
...
// a few nested returns and functions ...
    var h = g.historyItems, c = h.concat(a);
1

1 Answers

0
votes

Indeed it was a trivial matter.

It turns out that the selectionText property is defined in the externs file, while the historyItems is set in chrome's storage by me. Because of that, the same style of code leads to different behavior.

Conclusion: what really matters is what is defined in the externs file.