Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing an ajax call in clojurescript

I'm new to clojurescript and would like to do a deeper dive by implementing a previously written application purely in clojurescript, but am at a loss with respect to to implement an ajax call. Can anyone point me to an example online or provide me with a code snippet or two?

like image 692
Marc Avatar asked Dec 18 '11 20:12

Marc


3 Answers

January 22, 2016 update

Although it still works, the original answer is from a time when there was a general lack of ClojureScript solutions with more than 1 contributor. Rather than leveraging XhrIo directly, definitely consider using a well-maintained, feature-rich solution that wrappers it instead like cljs-ajax, as suggested by Mikhail D below!


Okay, So given that Clojurescript leverages Google's Closure JavaScript library, a quick search of the Closure Documentation yielded xhrIo as the proper method for generating AJAX calls:

Example using Closure's Asynchronous XMLHttpRequests with XhrIo

goog.net.XhrIo.send(url, opt_callback, opt_method, opt_content,
     opt_headers, opt_timeoutInterval)

A quick review of the Clojurescript source revealed the following function:

From src/cljs/clojure/browser/net.cljs in clojure / clojurescript

(defn xhr-connection
  "Returns an XhrIo connection"
  []
  (goog.net.XhrIo.))

So something along the lines of this should have the intended results:

(def xhr xhr-connection)

(defn myCallback [replyValue] 
  ... Do Something with replyValue
  ... for example: (someJsonFunc (.getResponseJson (.target replyValue))))

(defn ajax-json [url]
   (.send xhr url myCallback))

For JSONP, you can do something similar using the goog.net.Jsonp. See the link for details:

JSONP Closure API

Hope someone finds this helpful!

like image 51
Marc Avatar answered Sep 20 '22 18:09

Marc


An another viable option could be https://github.com/JulianBirch/cljs-ajax

Since it's designed for ClojureScript, the syntax looks clearer and simpler. It also supports a lot of features out of the box (for example: transit, edn and json formats).

Some examples from a README:

(ns foo
  (:require [ajax.core :refer [GET POST]]))

...

(GET "/hello" {:handler handler
               :error-handler error-handler})

(POST "/send-message"
    {:params {:message "Hello World"
              :user    "Bob"}
     :handler handler
     :error-handler error-handler})
like image 42
Mik Avatar answered Sep 18 '22 18:09

Mik


The way I did it is slightly different. I don't know why the way that Marc suggested in his answer didn't work for me. Hopefully this is also useful.

I used goog.net.XhrIo directly, rather than the xhr-connection wrapper.

(defn callback [reply]
    (let [v (js->clj (.getResponseJson (.-target reply)))] ;v is a Clojure data structure
        (your-function-here v)))

(.send goog.net.XhrIo url callback)

The main difference that I can see is that I've used .-target to get the property of the JSON object, rather than calling target.

It's worth noting that maps in v that have been created from JSON objects are keyed by strings not keywords.

like image 40
Andrew Avatar answered Sep 18 '22 18:09

Andrew