Fork me on GitHub
#beginners
<
2017-07-13
>
gdeer8101:07:39

I poked my head out of the backend for two seconds and the front end just dumps all over me. I'm turning a command line app into a SPA. Right now it makes rest calls to a service I don't own and I get a response without issues. But when I try to make those rest calls from the frontend I get nothing but trouble

gdeer8101:07:22

so i'm guessing I have to make the frontend calls to a backend service I own that makes the rest calls or whatnot

gdeer8101:07:51

an extra layer of coordination

noisesmith01:07:29

yeah- likely you are running into xss issues?

gdeer8101:07:04

getting the message No 'Access-Control-Allow-Origin' header is present on the requested resource

gdeer8101:07:53

my google foo wasn't very good last night. just now I searched for "clojurescript CORS" I see a google groups post from 2014 where someone had the same issue I was 😁

noisesmith01:07:26

also, for almost anything, you can just use the javascript answer

noisesmith01:07:32

the translation is trivial

noisesmith01:07:00

(or in jvm clojure, the java answer - though that can be trickier with cases involving inheritance)

gdeer8101:07:04

that's true, googling "javascript cors" also provided helpful results

bschrag02:07:56

Any clue what's wrong here? Desired function call fails. Function body succeeds.

(def ^:dynamic *global-transient*)
(defn test []
  (assoc! *global-transient* ; Side effect, only.  update! (?)
          "keyString"
          (conj (or (get *global-transient* "keyString")
                    [])
                {"keyString" "replaceMe?"})))

edit-server.core> (let [*global-transient* (transient {})]
                    (test))
ClassCastException clojure.lang.Var$Unbound cannot be cast to clojure.lang.ITransientAssociative  clojure.core/assoc! (core.clj:3259)
edit-server.core> (let [*global-transient* (transient {})]
                    (assoc! *global-transient* ; Side effect, only.  update! (?)
                            "keyString"
                            (conj (or (get *global-transient* "keyString")
                                      [])
                                  {"keyString" "replaceMe?"})))
#object[clojure.lang.PersistentArrayMap$TransientArrayMap 0x38327a4e "[email protected]"]
edit-server.core> 

noisesmith02:07:00

let bindings and vars are not interchangable

noisesmith02:07:15

sorry for the wrong answer before, I misread

noisesmith02:07:55

not using the return value of assoc! is incorrect - it sometimes accidentally works, but it is guaranteed to break when certain size boundaries are crossed

noisesmith02:07:13

@bschrag but the specific problem here is just due to how values are resolved - a let binding shadows a var (that is, hides its name in code compiled within that scope), but does not replace it or fill it in

noisesmith02:07:17

what happens when you don't use the return value of assoc!

user=> (let [t (transient {}) _ (apply assoc! t (range 32)) m (persistent! t)] (map m [0 2 4 14 16 30]))
(1 3 5 15 nil nil)

noisesmith02:07:09

simpler example of what went wrong in the original code:

+user=> (def x)
#'user/x
+user=> (defn get-x [] x)
#'user/get-x
+user=> (let [x 2] (get-x))
#object[clojure.lang.Var$Unbound 0x30b19518 "Unbound: #'user/x"]

bschrag02:07:09

@noisesmith So, this is wrong, too (but different):

edit-server.core> (def ^:dynamic x 2)
#'edit-server.core/x
edit-server.core> x
2
edit-server.core> (defn get-x [] x)
#'edit-server.core/get-x
edit-server.core> (get-x)
2
edit-server.core> (let [x 1] (get-x))
2
I had better study up on Clojure scope. (It's not Common Lisp...) 😳 Thanks!

noisesmith02:07:03

@bschrag you can change a dynamic binding in a scope with binding

noisesmith02:07:46

when a form is compiled, the actual value being captured is what's important (whether a var or local binding or whatever), not the name

nmax12:07:07

Hi everyone! I have the following code:

(for [elem1 list1]
  (for [elem2 (.getElem2 elem1)]
    (for [elem3 (.getElem3 elem2)
          :when (...)]
      elem3)))
It works perfectly except when the
:when
statement does not match. In this case I ended up with list like:
(elem3-1 elem3-2 (()))
because for always return empty list. How can I eliminate these empty lists?

nmax12:07:28

I tried doseq but it returns nil and I can't came up with an idea how I can store elements from it

rauh13:07:27

@nmax (for [elem1 list1, elem2 (...), elem3 (...) :when ...] elem3)

nmax13:07:25

@rauh Thanks, it works!

bschrag18:07:19

Are there some rules dictating when CIDER responds to a Java compiler error by highlighting source code with that nice red underlining? I frequently find myself confronted with cryptic error messages and only a stack trace to work with.

josh_tackett19:07:09

Hey guys any advice for the best unit test CI tool?

shaun-mahood20:07:45

Does anyone have any good resources to understand the Java/servlet stuff works (more specifically, the things that would help me understand the parts that ring uses)?

noisesmith20:07:51

I don’t have a good doc handy, but it’s more accurate to say the servlet uses ring - ring implements something the servlet uses to create a web http handler

noisesmith20:07:24

the servlet container decides what the route and port are, the ring app decides how to handle a request

mobileink20:07:08

@shaun-mahood do you have a specific problem or just looking for an overall view?

shaun-mahood20:07:19

Mainly looking for an overall view, though the specific thing I eventually want to be able to do is understand enough to understand or translate Java examples dealing with authentication and security.

shaun-mahood20:07:06

But having never dealt with the java web stack (or java) outside of using clojure I definitely am missing some basics.

mobileink20:07:17

you may find the docs at https://github.com/migae/boot-gae/blob/master/README.adoc#servlets useful. see esp. the bits about defservice.

mobileink20:07:11

also, keep a copy of the Java Servlets spec handy. It's quite readable.

mobileink20:07:20

np. warning: to use servlets you must use gen-class afaik. but the gen-class docs are notorious. if you find them a little indecipherable just ask.

pitalig20:07:10

Hey guys, I'm searching for some advices on separing my application logic from database interaction, do you recoment any article or text where I can get tips about that? I'm creating an app with clojure and postgresql, but I should use less sql as possible, so my ideia is to have a function that query a complete table and other functions that use this data will always receive it as an argument, then I will be respecting the rule "call the same function with exactly the same arguments should always return the same results". Is that correct?

donaldball20:07:09

For apps where disentangling the persistence logic from the application logic is a relevant consideration, I’ll reach for one or more protocols which describe the database interactions required. For example, a UserDatabase protocol might have list-all-users find-user and update-user fns.

eriktjacobsen21:07:02

@pitalig https://github.com/stuarthalloway/presentations/wiki/The-Impedance-Mismatch-is-Our-Fault Normally, you'd want to figure out how to model your data in Clojure (which will probably look different from a normalized sql table structure), and then work with that data model everywhere in your code, and only deal with sql when you're loading or storing that data model.

pitalig21:07:48

Thank you guys!