Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pull an integer out of localstorage and coerce to an integer using clojurescript

I'm trying to pull an integer out of localStorage with a simple clojurescript app. Everything I've tried ended up trying has some sort of wrong behavior.

Below is my program without initializing from local storage. I'll ignore the key not found case since I've a JQuery version that handles that to prime the storage. Also, the JQuery app reads the ClojureScript saves to localStorage fine. So that's working for me.

Quick summary is this. I message says "There have been $number days since the last incident" The $number is in a div named "counter." I've got three buttons; one increments the count, one decrements the count, and the last resets the count to zero.

 (ns days.core
        (:require [goog.events :as events]
                  [goog.string :as string]
                  [goog.math.Integer :as int]
                  [goog.dom :as dom]))
    (defn initial-state [] 0)
    (def count (atom (initial-state)))
    (defn set-counter [n]
       (do (.setItem (.localStorage (dom/getWindow)) "count" n)
           (dom/setTextContent (dom/getElement "counter") n)))
    (defn set-button-fn [button-id f-update]
       (events/listen (dom/getElement button-id)
                      "click"
                      (fn [] (do (f-update) (set-counter @count)))))
    (defn start-app []
       (do
           (set-counter @count)
           (set-button-fn "addDay" (fn [] (swap! count inc)))
           (set-button-fn "decDay" (fn [] (swap! count dec)))
           (set-button-fn "reset" (fn [] (reset! count 0)))))
    (start-app)

When I try to use goog.math.Integer.fromString() to cast to an integer, the call to inc will append a 1 on the end (7 went to 71 and 711). The call to dec will do what I expect, decrement it numerically (711 went to 710 and 709). Here's how I'm trying to initialize that.

(defn initial-state []
  (integer/fromString (.getItem (.localStorage (dom/getWindow)) "count")))

I realized this was a goog.math.Integer object so I tried to call .toNumber() on it. But this and .toInt() seemed to give me a function. function (){if(this.e==-1)return-w(this).D();else{for(var a=0,b=1,d=0;d=0?e:Ua+e)b;b=Ua}return a}} to be exact.

(defn initial-state [] (.toNumber 
  (integer/fromString (.getItem (.localStorage (dom/getWindow)) "count"))))

Clojure seems to use java's Integer class to cast from a string to an int even to the point of having (int "1") throw so that idea was shot.

I also tried to call javascript's parseInt(). This is how I do it in the JQuery version. However the ClojureScript call always returns a 1. Even if my JQuery version stores an 8 as evidenced by Chrome's developer tools.

(defn initial-state []
  (.parseInt (dom/getWindow)
             (.getItem (.localStorage (dom/getWindow)) "count")))

Any ideas how I can get that string value to behave as an integer? It's got to be simple, but I'm getting nowhere.

like image 971
Ball Avatar asked Jul 27 '11 02:07

Ball


2 Answers

Here's a method that works in both Clojure and ClojureScript:

(defn- str->int [s]
  #?(:clj (Integer/parseInt s)
     :cljs (js/parseInt s)))

(str->int "10")
> 10
like image 124
bmaddy Avatar answered Nov 05 '22 01:11

bmaddy


You can access the parseInt function via the js namespace like so:

(js/parseInt "7")
like image 22
Daniel Thompson Avatar answered Nov 05 '22 00:11

Daniel Thompson