Giter Club home page Giter Club logo

cljs-ajax's People

Contributors

bfontaine avatar camdez avatar daveliepmann avatar djebbz avatar govloop-deploy avatar honzabrecka avatar hugoarregui avatar ifesdjeen avatar jherrlin avatar jmlsf avatar jpmonettas avatar julianbirch avatar kaliszad avatar kanwei avatar ktsuji avatar malcolmsparks avatar markdingram avatar mdonjones avatar mynomoto avatar radicalzephyr avatar rodnaph avatar rosejn avatar ryanbertrand avatar shark8me avatar srwiseman avatar thomasmulvaney avatar whamtet avatar xcthulhu avatar yogthos avatar zjhmale avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cljs-ajax's Issues

Idea: GET should default to using a prefix on JSON

You'd still be able to override to the unsafe behaviour, but it would be good if our default was safe. Prefix should probably be while(1); which would mean that the default also worked against google APIs.

[Newbie] Iterating over a response

Apologies for the newbie question.

I'm doing a GET and the response is a list of items (json). I can see the result in the network tab. When I print the result I see it is a cljs.core.PersistentVector. When I map over the result each item is a cljs.core.PersistentHashMap. However, I can't access the items inside the map (e.g. (:key map-item)). If I print the keys and vals of the each map I can see the correct items are there, so I'm very confused as to why __(:key ma-item) is not working. I'm pretty sure I'm missing something basic. Would appreciate some pointers.

Sorry for posting this basic question here, have been googling for hours and couldn't find a solution.

ajax-request documentation broken in README.md

I have just upgraded a project that depended on v0.2.6 to v0.3.3.

I was using the ajax-request defn rather than the GET macro. I have changed my code to use the GET macro because one of the defns that I was using, json-format, is no longer in the code.

Trying to use the documentation as a guide, I couldn't find the codec defn either.

Use core.async?

More a question than an issue: should the API be redesigned to use channels?

Truly JSON responses

I have a use-case where I need the JSON from the .getResponseJson to remain in JSON format. When I used :response-format :json it still gets converted to EDN. In this case I need it in JSON format so I can pass it to another library.

Is this something you could support?

Otherwise I have to convert the EDN back into JSON which feels wasteful, or use goog.xhrio directly. :(

No way to access response headers

Hi,

I've been looking into using cljs-ajax for a smaller project of mine, but I need to be able to access the request's response headers.

My idea was to implement a new handler that would forward the response headers, but they seem to get swallowed in base-handler/js-handler.

What would be the best way to modify this project to expose the response headers?

GET with :headers transforms into OPTION request

(GET "/users" {:handler handle-users
               :error-handler handle-error
               :headers {"X-api-key" "my-app-key"
                         "Accept" "application/edn"}})

I get a 404 because it tried to send a request method of OPTIONS instead of GET.

If I leave out :headers it does in fact issue a GET request, but it fails on the server for obvious reasons; there is no request header of X-api-key.

first "word" only returned from text/html

Here is my implementation of the GET function:

(defn send-to-say [message]
  (GET "/say" {:params {:greeting message}
               :handler (fn [response]
                            (.log js/console  (str response)))}))

The output from the GET handler function, to the console, is <p>You , the first "word" only.
The response from the server, as seen in the chrome network tab is:
<p>You said: test</p> with headers:

HTTP/1.1 200 OK
Date: Sat, 07 Jun 2014 15:07:47 GMT
Content-Type: text/html;charset=UTF-8
Content-Length: 21
Server: Jetty(7.6.8.v20121106)

It looks like the server side is behaving correctly.
Here is my action using compojure and hiccup:

(defn say [params]
  (html [:p (format "You said: %s" (get params "greeting"))]))

I must be missing something. Thanks for your help.

:format parameter to indicate the response format?

The README (and the docstrings for GET and POST functions) says that :format indicates the response format. Shouldn't this indicate the request format actually? This ClojureScript code running in the browser doesn't know which will be the format of the server response (at most it can specify a preferred format using the HTTP Accept: header), but it can choose how to format the request.

On the other hand, the only way to specify the data to send according to the README is the :params option, but I found that the contents of :params is not affected by the value of :format, and it's always sent as application/x-www-form-urlencoded. Digging through the code I finally found that I could get the expected behaviour (i.e. data sent encoded in the specified format) if the data to send is specified in a :data option (instead of :params), which is not mentioned in the README. I also see that the data to send can be specified in a third way, using a :bodyoption. Why these 3 different ways?

Finally, I guess a component is needed in the server-side to parse EDN or JSON, isn't it? Something like ring-edn and ring-json?

Add PATCH verb

PATCH is a HTTP verb. Perhaps it could be added to the easy-api's.

(m/easy-api PATCH)

I think this is a one-liner but perhaps there's more to it. I note that the Django REST Framework documentation talks about PATCH as a browser enhancement.

is cljs-ajax sync or async by default?

I would like to know how cljs-ajax handles an ajax request where the server might take several seconds to respond, or never respond at all. Does the rest of the cljs app block (does the JS stop execution) while waiting? XHR can be either sync or async and I'm curious how cljs-ajax handles this.

DELETE without `:params` sends request body `null`

The following call

(DELETE "http://localhost:3000"
        {:format (json-request-format)})

makes an http DELETE request with the request-body null and Content-Length 4 even if no :params are specified.

This is problematic at least on Google App Engine as the web server won't allow a body in DELETE requests

CSRF token support

It might be an idea to provide a key like :csrf-token that would be used to pass a CSRF token in the request. Since ring-defaults enables CSRF protection by default, and the token should be format independent, it would be nice to be compatible with the ring-anti-forgery middleware format.

Specify Accept header

It would be useful to be able to specify the HTTP Accept header used in the request, especially for REST resources.

Unroll keyword args to ajax-request

It would be nice if ajax-request followed this guideline from the Library Coding Standards:

Unroll optional named arguments. Callers should not have to wrap optional named arguments in a map literal:

(release-sharks 2 :laser-beams true)    ; good
(release-sharks 2 {:laser-beams true})  ; bad

I looked to see if I could easily submit a PR for this, and noticed there's an undocumented fourth parameter to ajax-request, used in one of the tests. Can this be made an option, or, if it's only for internal/testing use, maybe use with-redefs in the test instead?

In EDN responses the longs are always parsed to 0 in IE8

I made a simple server that returns this:

HTTP/1.1 200 OK
Content-Length: 43
Content-Type: application/edn; charset=utf-8
Date: Sat, 05 Jul 2014 15:44:29 GMT
Server: http-kit

{:s "string", :l 42, :k :keyword, :d 1.337}

In my ClojureScript client I get this with:

(GET "/data" {:handler show-result})

In Chrome, Firefox and IE10 I get the expected result, but in IE8 the value of :i is 0.

Versions:

[org.clojure/clojurescript "0.0-2234"]
[cljs-ajax "0.2.6"]

Compiled with :whitespace optimisation.

Handlers called multiple times on file upload

I'm trying to do a file upload and handle progress events, but experiencing weird behaviour where the error handler is spuriously called and the success handler is called multiple times. I've created a minimal reproducing example project based on the reagent-figwheel template here: https://github.com/rsslldnphy/cljs-ajax-fileupload-issue.

The most relevant part is in cljs-ajax-fileupload-issue.core, which I'll reproduce here:

(defn do-upload
  [e]
  (let [f         (first (array-seq (.-files (.-target e))))
        filename  (.-name f)
        form-data (js/FormData.)
        xhr       (js/XMLHttpRequest.)]
    (.append form-data "filename" filename)
    (.append form-data "file" f)
    (-> xhr
        .-upload
        (.addEventListener "progress"
                           #(.log js/console "Made progress") false))
    (ajax/POST "/uploads" {:api xhr
                           :processData false
                           :params form-data
                           :handler #(js/alert "Finished file upload")
                           :error-handler #(js/alert "Failed file upload")})))

(defn page []
  [:div [:h1 "Upload file below"]
   [:input {:type "file" :on-change do-upload}]])

When I upload a file using this code, I see:

  • An immediate alert saying "Failed file upload"
  • Logging in the browser console "Made progress" multiple times depending on the size of the file
  • Three alerts in turn saying "Finished file upload"

I'm guessing it's perhaps something to do with me using XMLHttpRequest? Maybe it calls the handler with some extra events which get interpreted as success or failure?

Oh - and I just changed the error-handler to console log the response, and it appears to have a status of 0 if that helps.

turn off console logging?

Hi, this library works nicely, but I'm wondering if it is possible to turn off the logging to the browser console that says XHR finished loading?

Closure library problems

After requiring ajax.core module I catch errors in my console:

Uncaught TypeError: undefined is not a function useragent.js:31
Uncaught TypeError: undefined is not a function disposable.js:81
Uncaught TypeError: undefined is not a function listener.js:110
Uncaught TypeError: undefined is not a function events.js:146
Uncaught TypeError: undefined is not a function json.js:33
Uncaught TypeError: undefined is not a function functions.js:277
Uncaught TypeError: undefined is not a function debug.js:30
Uncaught TypeError: undefined is not a function logrecord.js:104
Uncaught TypeError: undefined is not a function logbuffer.js:64
Uncaught TypeError: undefined is not a function logger.js:105
Uncaught TypeError: undefined is not a function log.js:34
Uncaught TypeError: undefined is not a function xmlhttp.js:49
Uncaught TypeError: undefined is not a function xhrio.js:222
Uncaught TypeError: undefined is not a function xhrio.js:71

It seems goog.define is not being defined. Removing [ajax.core :refer [GET POST]] solves problem.

Call finally with response

Can finally also receive the response?
My use-case is adding some interceptors which dispatch on certain http statuses.

Incorrect URL generation for arrays

(GET "/data"
     {:params {:a ["a", "b", "c"]}})

Generates request to

/data?a=a&a=b&a=c

While it should generate a request to (although i still can't find an RFC, but that's what many people do)

/data?a%5B%5D=a&a%5B%5D=b&a%5B%5D=c

Any hints?

Remove warning when running tests

When you run the tests, you get a warning that ajax.core.AjaxImpl is not a protocol.

  • It is a protocol
  • The code actually works

I can't figure out what on earth causes this error to happen, I've asked on IRC, still no idea.

I'd be very glad if someone could figure out what I'm doing wrong on this.

Enable ajax cancellation

No-one's needed it so far, but sooner or later someone will. A good candidate for a pull request. Make ajax-request return a value that can later be cancelled.

Handle timeouts

The code now has support for setting a timeout parameter, but I haven't tested how timeout feedback works, so this is not really finished.

Empty responses

Maybe also allow empty responses to be EDN instead of EOF while reading Format should have been EDN (default)
Sometimes only the successful response is enough and the error response has content.

Empty response in handler

I'm trying to implement a simple AJAX-query to get a map structure from server.

This is my request:

(GET "/search" {:handler handler 
              :params {:q (:text (deref data))}
              :format :transit
              :response-format :transit                  
              :error-handler (fn [data] (println 123123))})

And this is handler:

(defn handler [response]
  (.log js/console "11111")
  (.log js/console (str response)))

Handler gets nothing:

image

I also can see a good response in Network tab:

image

Add "finally" function to options map

Suggestion: Add a key to the options map which contains a function which is always called after the response/error handler.

I find myself duplicating code in the end of the normal handler and error handler to re-enable form buttons and change classes in the DOM which visualized that an action was waiting for a response. But I supposed it would have other use cases.

The key could be called finally (like when working with exceptions).

keywordize-keys?

Should have an option to keywordize-keys when parsing a JSON response? not sure how this goes down with EDN

test failing

I'd like to help but the tests are failing. Installed Phantomjs 1.9.7 on osx + Clojurescript.Test and getting this message

$ lein test
Compiling ClojureScript.
Compiling "target/main.js" from ["src"]...
Compiling "target/main.js" failed.
clojure.lang.ExceptionInfo: {:tag :cljs/analysis-error}
at clojure.core$ex_info.invoke(core.clj:4327)
at cljs.analyzer$error.invoke(analyzer.clj:268)
at cljs.analyzer$analyze.invoke(analyzer.clj:1522)
at cljs.analyzer$analyze.invoke(analyzer.clj:1519)
at cljs.compiler$parse_ns$fn__5022$fn__5023.invoke(compiler.clj:959)
at cljs.compiler$parse_ns$fn__5022.invoke(compiler.clj:959)
at cljs.compiler$parse_ns.invoke(compiler.clj:954)
at cljs.compiler$parse_ns.invoke(compiler.clj:949)
at cljs.compiler$to_target_file.invoke(compiler.clj:1037)
at cljs.compiler$compile_root.invoke(compiler.clj:1069)
at cljs.closure$compile_dir.invoke(closure.clj:341)
at cljs.closure$eval5363$fn__5364.invoke(closure.clj:381)
at cljs.closure$eval5300$fn__5301$G__5291__5308.invoke(closure.clj:292)
at cljs.closure$eval5350$fn__5351.invoke(closure.clj:395)
at cljs.closure$eval5300$fn__5301$G__5291__5308.invoke(closure.clj:292)
at cljsbuild.compiler.SourcePaths$fn__5559.invoke(compiler.clj:44)
at clojure.core$map$fn__4207.invoke(core.clj:2485)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
at clojure.lang.RT.seq(RT.java:484)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$apply.invoke(core.clj:617)
at clojure.core$mapcat.doInvoke(core.clj:2514)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at cljsbuild.compiler.SourcePaths._compile(compiler.clj:44)
at cljs.closure$build.invoke(closure.clj:955)
at cljs.closure$build.invoke(closure.clj:923)
at cljsbuild.compiler$compile_cljs$fn__5570.invoke(compiler.clj:58)
at cljsbuild.compiler$compile_cljs.invoke(compiler.clj:57)
at cljsbuild.compiler$run_compiler.invoke(compiler.clj:158)
at user$eval5696$iter__5699__5703$fn__5704.invoke(form-init2101836119125145764.clj:1)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
at clojure.lang.RT.seq(RT.java:484)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$dorun.invoke(core.clj:2780)
at clojure.core$doall.invoke(core.clj:2796)
at user$eval5696.invoke(form-init2101836119125145764.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6619)
at clojure.lang.Compiler.eval(Compiler.java:6609)
at clojure.lang.Compiler.load(Compiler.java:7064)
at clojure.lang.Compiler.loadFile(Compiler.java:7020)
at clojure.main$load_script.invoke(main.clj:294)
at clojure.main$init_opt.invoke(main.clj:299)
at clojure.main$initialize.invoke(main.clj:327)
at clojure.main$null_opt.invoke(main.clj:362)
at clojure.main$main.doInvoke(main.clj:440)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
at cljs.core$import_macros$fn__5761.invoke(core.clj:49)
at clojure.core$map$fn__4207.invoke(core.clj:2485)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
at clojure.lang.RT.seq(RT.java:484)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$map$fn__4211.invoke(core.clj:2490)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:67)
at clojure.lang.RT.seq(RT.java:484)
at clojure.core$seq.invoke(core.clj:133)
at clojure.core$concat$cat__3925$fn__3926.invoke(core.clj:687)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
at clojure.lang.Cons.next(Cons.java:39)
at clojure.lang.RT.next(RT.java:598)
at clojure.lang.Compiler.eval(Compiler.java:6606)
at clojure.lang.Compiler.load(Compiler.java:7064)
at clojure.lang.RT.loadResourceScript(RT.java:370)
at clojure.lang.RT.loadResourceScript(RT.java:361)
at clojure.lang.RT.load(RT.java:440)
at clojure.lang.RT.load(RT.java:411)
at clojure.core$load$fn__5018.invoke(core.clj:5530)
at clojure.core$load.doInvoke(core.clj:5529)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at cljs.analyzer$load_core.invoke(analyzer.clj:210)
at cljs.analyzer$analyze$fn__4037.invoke(analyzer.clj:1528)
at cljs.analyzer$analyze.invoke(analyzer.clj:1524)
... 49 more
Tests failed.

Use a transit reader for JSON responses?

I notice when using JSON, js->clj is used to convert over to cljs data structures. According to this using a transit JSON reader would be faster. It does mean the keys have to be strings though which might be a deal breaker.

What do you think? I'm not sure this is a good idea, so I figured I'd throw it out there for discussion.

An alternative is to just set cljs-ajax to transit mode, and have the server return plain JSON anyway. I think that should work. The only caveat there is the server needs to be ready for accept containing application/transit+json.

EDN GET request parameters

Hi @yogthos,
I'm using edn as the data format for the req and response of a get request, but because the data is added to the query string, two problems occur:

  • keywords as values (not keys) are stringified, and the ring wrap-edn-params middleware interprets them as strings (keyword keys make it across just fine)
  • nil values are appended as "null", which on the server ends up as the string "null"

As a work around I added some ring middleware to get the actual params, but I wanted to know whether the behavior I just described is expect or whether a patch to change it would be considered.
Thanks,
Tom

POST not working correctly - am I missing something?

I have a simple event handler that works like this:

(defn attempt-to-sign-in! [event]
  (.preventDefault event)
  (let [email (.-value (.getElementById js/document "email-field"))
        password (.-value (.getElementById js/document "password-field"))
        handler #(set! (.. js/window -location -href) "/")]
    (POST "/api/authenticate" {:params {:email email :password password}
                               :keywords? true
                               :response-format :json
                               :handler handler})))

When I examine the payload that this request creates, it's this:

["^ ","~:email","[email protected]","~:password","password123"]

This seems very wrong. Is it my fault or is this a bug?

require GET POST

I'm new to clj & cljs and I can't find the way to require POST ans GET method, when I use the readme samples I can't use POST nor GET
(:require [ajax.core :refer [GET POST]])
request-ajax is fine.
Even looking at src code didnt help me

:response-format required?

I'm using the "0.3.0-SNAPSHOT" (I need the file upload support).

According to docs, if :response-format is left blank, the format is detected from the Content-Type header. However,

(ajax.core/POST "/upload" {:params (js/FormData. form-node)})
; =>
; Uncaught Error: unrecognized response format:
;   get_response_format
;   ajax_request
;   easy_ajax_request
;   POST__delegate

If the :response-format is added then it works, ex.

(ajax.core/POST "/upload" {:params (js/FormData. form-node
                           :response-format :edn)})

Document non-HTTP error behavior

cljs-ajax's readme is mostly pretty comprehensive (well done everyone!) but it does not seem to mention how it handles non-HTTP errors, such as timing out waiting for a response, or failing to contact the destination server at all.

What does cljs-ajax do then? Throw? Return some kind of error object? I'd like to see this in the readme (forgive me if I missed it).

Split out EDN support

There are no good use cases for EDN on the browser with the advent of transit. Move EDN formats into a separate namespace and remove EDN from format detection.

This would be a breaking change, so 0.4.0 at the earliest.

At some point, EDN support should be removed entirely.

Clarify License.

It's a minor issue, but it'd be really useful if you could make the license for the project a bit more obvious. I know that you specify the Eclipse public license in your project.clj, but it'd be great if you could include that in the README and/or include a LICENSE file.

Thanks!

Support XHR withCredentials

It would be nice to have support for setting the withCredentials attribute on the XHR object so the ajax request can set and read cookies etc.

Looking around the Google Closure API docs, this can either be done with an argument passed to the XhrIo constructor or by calling setWithCredentials(true) on it preflight.

I have tried to do this myself but I can't make it work. I'll issue a PR if I get anywhere.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.