0

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.

Alan Thompson
  • 29,276
  • 6
  • 41
  • 48
nenad
  • 409
  • 3
  • 14
  • 1
    Perhaps the request has no `:business-partner` key. – amalloy Mar 25 '20 at 04:27
  • to expand on what @amallow wrote: it seems to me that your response could be encoded, and you need to use a reader before you are able to extract a `:business-partner` out of it. Check the example here: https://github.com/cognitect/transit-cljs/wiki/Getting-Started#reading – Denis Fuenzalida Mar 25 '20 at 05:48

1 Answers1

3

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"
Alan Thompson
  • 29,276
  • 6
  • 41
  • 48
  • Yes, I did it. Check again my post to see what happens when did it.I 've edited it. – nenad Mar 25 '20 at 17:02
  • Solved! Thank you a lot! I've been receiving a map, one simple object, but as you explained that map should have been actually value of the :business-partner key. So, you opened my eyes. I added a :business-partner key on the server endpoint on the right place and now it works. Thank you Alan, you helped me more than you can imagine. In the future the grab function you mentioned will be my best friend i think. – nenad Mar 25 '20 at 17:39