I made service endpoint api for getting single object by id and it works as expected. I tested it with Postman and in handler function. I use cljs-ajax library for asynchronous client. I cant change the state of Reagent atom when I get response. Here is the code:
(ns businesspartners.core
(:require [reagent.core :as r]
[ajax.core :refer [GET POST]]
[clojure.string :as string]))
(def business-partner (r/atom nil))
(defn get-partner-by-id [id]
(GET "/api/get-partner-by-id"
{:headers {"Accept" "application/transit+json"}
:params {:id id}
:handler #(reset! business-partner (:business-partner %))}))
When I tried to access business-partner atom I got nil value for that atom. I can't figure out why because another method is almost the same except it get's list of business partners and works fine.
When I change the get-partner-by-id function:
(defn get-partner-by-id [id]
(GET "/api/get-partner-by-id"
{:headers {"Accept" "application/transit+json"}
:params {:id id}
:handler (fn [arg]
(println :handler-arg arg)
(reset! business-partner (:business-partner arg))
(println "Business partner from handler: " @business-partner))}))
Output in the browser console:
:handler-arg {:_id 5e7ad2c84b5c2d44583e8ecd,
:address Main Street,
:email nenmit@gmail.com,
:phone 555888,
:name Nen Mit}
Business partner from handler: nil
So, as you can see, I have my object in handler as desired, but when I try to reset my atom nothing happens. That's the core of the problem I think. Thank you Alan.
When in doubt, use debug print statements. Make your handler look like this:
:handler (fn [arg]
(println :handler-arg arg)
(reset! business-partner (:business-partner arg)))
You may also want to use clojure.pprint/pprint
to pretty-print the output, or also add (type arg)
to the output.
You may also want to initialize the atom to a specific value like
:bp-default
so you can see if the nil
you observe is the original one or if it is being reset to nil
.
Update
So it is clear the key :business-partner
does not exist in the map you are receiveing. This is what you must debug.
Trying to pull a non-existent key out of a map always returns nil
. You could also use the 3-arg version of get
to make this explicit. Convert
(:business-partner arg) => (get arg :business-partner ::not-found)
and you'll see the keyword ::not-found
appear in your atom, verifying what is occurring.
In order to catch these problems early, I nearly always use a simple function grab
from the Tupelo library like so:
(:business-partner arg) => (grab :business-partner arg)
The grab
function will throw an exception if the expected key is not found. This provides early-warning of problems so you can track them down faster.
Another hint: next time use prn
instead of println
and it will retain double-quotes on string output like:
"Main Street"