I'm trying to use Google's recaptcha in a Clojurescript/Reagent SPA as seen in the code below.
(ns myapp.captcha
(:require [reagent.core :as r]
[cljs.core.async :refer [<! >! chan]])
(:require-macros [cljs.core.async.macros :refer [go go-loop]]))
(def captcha-ch (chan))
(defn ^:export data-callback [human-proof]
(go (>! captcha-ch {:captcha-data human-proof})))
(defn ^:export data-expired-callback []
(go (>! captcha-ch {:captcha-expired true})))
(defn captcha [site-key]
(let [grecaptcha-script (doto (.createElement js/document "script")
(.setAttribute "id" "grecaptcha-script")
(.setAttribute "src" "https://www.google.com/recaptcha/api.js"))
out-ch (chan)
comp (r/create-class
{:component-did-mount (fn [this]
(.appendChild (.-body js/document)
grecaptcha-script))
:component-will-unmount (fn [this]
(.removeChild (.-body js/document)
(.getElementById js/document "grecaptcha-script"))
(go (>! captcha-ch {:exit true})))
:reagent-render (fn [this]
[:div.g-recaptcha
{:data-sitekey site-key
:data-callback "myapp.captcha.data_callback"
:data-expired-callback "myapp.captcha.data_expired_callback"}])})]
(go-loop []
(let [msg (<! captcha-ch)]
(if-not (:exit msg)
(>! out-ch msg)
(recur))))
{:chan out-ch :comp comp}))
When the captcha is solved and data-callback is supposed to be called I get an error saying:
ReCAPTCHA couldn't find user-provided function: myapp.captcha.data_callback
On the other hand if I call myapp.captcha.data_callback from the browser's debugger console the function is visible and executes correctly.
PS: For now please ignore the global chan, which is a different matter. In order to fix that I have to call captcha render explicitly and that puts me in some race conditions apparently related to the order of script loading. I admit that it might be a cleaner approach but for now it's interesting to see what the problem is here.