Search code examples
clojure

How to change atom map in clojure?


I'm new to clojure, and i need to update two values inside this atom:

(def app-state (atom {:id "1":status 0 :st 0}))

Im using the following:

(let [value (mod (+ (:st @app-state) 1) 4)]
    (swap! app-state update-in [:status] value)
    (swap! app-state update-in [:st] inc))

Im getting:

Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

Solution

  • The third argument to update-in takes a function but you are supplying a long (value) which is why you get an exception. You could use assoc-in instead which takes the value to associate in the map directly:

    (swap! app-state assoc-in [:status] value)
    

    However you should do the entire update to the state atomically within the function passed to swap! e.g.

    (swap! app-state (fn [{:keys [st] :as state}]
                        (let [st-next (inc st)
                              value (mod st-next 4)]
                           (merge state {:st st-next
                                         :status value}))))