Fork me on GitHub
#beginners
<
2016-12-19
>
nur06:12:34

I am this guy

nur06:12:57

and I just got myself clojure for the brave and true (borrow from library)

nur06:12:05

I hope there's room for another noob

roelofw06:12:41

@nur there is place for a lot of noobs here

olslash06:12:52

if you want a job faster, learn JS (my opinion)

olslash06:12:05

if you're just looking for a fun exercise, clojure is great

olslash06:12:12

it'll be hard to get an entry-level job with python (opinion again from reading a lot of job postings), same with elixir

tom07:12:53

@nur I read your post there, I'd say just learn Clojure. The way of doing things will carry over into more languages, for the better. I know I got better. With regard to work, I work as a contractor (and I hire subcontractors here), and I do 95% Clojure. The other 5% is split between Python and JS. But naturally it'll be easier to get work in JS overnight if you want into the oldest profession.

olslash07:12:13

would be interested to hear about how you get consistent clj contracting work

olslash07:12:23

are you choosing the stack most of the time?

tom07:12:28

Yes, almost always. I market myself as a consultant, rather than as a code monkey. A lot of team building, architecture, and such for new products or refactoring old ones.

olslash07:12:31

anyway @nur everyone here is happy to help

olslash07:12:38

stick with it

abhir00p07:12:56

Hi I am trying to run a long running method

abhir00p07:12:04

And i want to track it via jmx

abhir00p07:12:14

the code i currently wrote looks like this

abhir00p07:12:28

(defn- start-long-running-method []
  (let [start-ts (ts/now)]
       (jmx/register-mbean
        (jmx/create-bean (ref {:time-elapsed (- (ts/now) start-ts)}))
        “my.namespace:name=Foo")
       (start-long-running-method)))

abhir00p07:12:24

but when I try to do (jmx/read “my.namespace:name=Foo” :time-elapsed) I keep getting 0

abhir00p07:12:36

So how do i dynamically update the current time?

agile_geek08:12:12

Try passing :time-elapsed as a lambda (an anonymous function) :time-elapsed #(- (ts/now) start-ts)

agile_geek08:12:33

Not sure that will work with interop but worth a try

abhir00p09:12:19

doesn’t work it says :time-elapsed as unavailable

poooogles13:12:53

qq, I'm trying to flatten a nested JSON structure into a map with the leaf key being the new key.

poooogles13:12:06

=>(let [test {:foo {:bar {:baz 123}} :qux false}]
      (flatten-record test)
  => {:baz 123, :qux false}

poooogles13:12:18

so far I've got...

poooogles13:12:20

(defn flatten-record
  "Take a nested record and recursively flatten "
  [record]
  (into {}
    (for [[k v] record]
      (if (map? v)
        (flatten-record v)
        {k v}))))

poooogles13:12:35

which seems to work, but I'm not sure if I could be doing something better here?

dominicm13:12:12

@poooogles clojure.walk/postwalk seems relevant.

poooogles13:12:45

yeah, honestly though I couldn't get my head around it

poooogles13:12:50

that was on Friday afternoon however.

dominicm13:12:04

There's a postwalk-demo in the namespace, which is fairly helpful

dominicm13:12:52

@poooogles I think your solution is good as it is really.

poooogles13:12:54

@dominicm cheers :thumbsup:

abdullahibra14:12:25

how can i generate all dates between two dates ?in string format like "yyyy-MM-dd"

dominicm14:12:16

@abdullahibra There are ways to format using SimpleDateFormatter: http://stackoverflow.com/a/14757757

dominicm14:12:02

To generate the dates, I'm not so sure there's a built-in way. So you'll need to use loop/recur or lazy-seq or something to generate them.

dominicm14:12:00

https://github.com/clj-time/clj-time#clj-timeperiodic you can do something like (take-while #(time/before? % my-end-date) (time.periodic/periodic-seq start-date (time/days 1)))

dominicm14:12:10

This requires a library though.

abdullahibra14:12:59

@dominicm thanks i figured it out : (mapv #(.withFieldAdded start (DurationFieldType/days), %) (range 0 (inc ndays)))

abdullahibra14:12:07

(mapv #(str (.withFieldAdded start (DurationFieldType/days), %)) (range 0 (inc ndays)))

roelofw15:12:13

I have this routes file in luminus :

(ns paintings2.routes.home
  (:require [paintings2.layout :as layout]
            [compojure.core :refer [defroutes GET]]
            [ring.util.http-response :as response]
            [ :as io]
            [paintings2.api-get :as api]
            [compojure.route :refer [resources]]
            [environ.core :refer [env]]
            [paintings2.api-get :as api]
            [clj-http.client :as client]))

(defn home-page []
  (let [url ""
        options {:as :json :query-params {:key (env :key) :format "json" :type "schilderij" :toppieces "True"}}]
    (layout/render
      "home.html" {:paintings (-> (client/get url options)
                                  api/read-numbers
                                  api/do-both-in-parallel-front)})))

(defn detail-page [id]
  (layout/render
    "detail.html" {:paintings (-> api/do-both-in-parallel-detail)}))


(defroutes home-routes
           (GET "/" [] (home-page))
           (resources "/")

           (GET "/detail/:id" [] (detail-page (:id)))
           (resources "/detail/:id"))  

roelofw15:12:42

what I try to do it that the id of the url is passed on to the detail page function so the right data can be downloaded from a external api. Right now I see this error message :

Wrong number of args passed to keyword: :id 

roelofw15:12:59

How can I make this work ?

delaguardo15:12:43

(GET "/detail/:id" [] (detail-page (:id))) -> (GET "/detail/:id" [id] (detail-page id))

roelofw16:12:40

oke, then I see output : paintings2.api_get$do_both_in_parallel_detail@133839f

roelofw16:12:58

and this

(defn detail-page [id]
  (layout/render
    "detail.html" {:paintings (api/do-both-in-parallel-detail id)}))  
`

roelofw16:12:28

gives this as output : clojure.lang.LazySeq@cbcb0ba1

roelofw16:12:08

so it looks the functions did not get applied

delaguardo16:12:58

Right, this is a result of using map - LasySeq. You can use mapv if you expect vactor in response from api/do-both-in-parallel

roelofw16:12:38

Thanks, that worked

roelofw16:12:50

wierd, on the FrontPage map works well

roelofw16:12:44

Now I can try to make a nice layout for the layout page

agile_geek16:12:10

@roelofw your code in the home.html template is probably forcing the realisation of the lazy seq. Remember 2 or 3 weeks ago I mentioned that map produced a lazy seq and it was not good practice to use map only for side effects (like IO- for example the calls to the api). mapv forces the lazy seq into a vector those realising the entire data structure. Another option would be to rewrite to use doseq instead of mapv

roelofw16:12:58

@agile_geek so I can better rewrite the parallel reading of the two data streams that I want to display on the pages ?

agile_geek16:12:25

You can just use mapv for now.

agile_geek16:12:51

@dominicm I was just about to link to that! 😉

roelofw16:12:29

oke, as I understand it right, I have to use doseq

roelofw16:12:46

time to hit the pages how that one works

agile_geek16:12:50

@roelofw as an exercise, try writing an application that maps over lines read from a file using line-seq and prints them to sys out and run it from the main method. You will find it does nothing.

roelofw16:12:21

I get the feeling that this first web application is more then I can chew at the moment

dominicm16:12:28

doseq doesn't return a value

roelofw16:12:23

@agile_geek so I have to make a file with some lines and use line-seq to read them and display them on a webpage or on the console ?

agile_geek16:12:35

@roelofw lazy sequences are something that takes a little getting used to when you come from an imperative language

roelofw16:12:57

yes, that is right

agile_geek16:12:42

@roelofw just try and print them to console in the main method by maping println over the sequence returned from line-seq and you'll see it does nothing.

agile_geek16:12:33

Then see if what happens with mapv

roelofw16:12:47

I will do that after dinner, if it's allright with you

agile_geek16:12:29

then try rewriting to use doseq

agile_geek16:12:21

@roelofw It's worth figuring out how lazy sequences work so you understand how they impact your desing with regard to I/O

roelofw16:12:59

oke, nice challenge for tonight and tomorrow

roelofw16:12:42

first challenge , find out how I can read a external file

agile_geek16:12:43

Try looking at the docs page for line-seq

roelofw17:12:37

hmm, I have made a file called test in the same directory as the core.clj file

roelofw17:12:46

but now the file cannot be found

roelofw17:12:02

must I place the file in another directory

agile_geek17:12:57

Depends what path you passed to the reader- assuming you are using a http://clojure.java.io/reader?

agile_geek17:12:43

If your jsut specified the filename with no path it will expect to find it in the top level project directory.

roelofw17:12:45

I have used this : (with-open [rdr ( "test")]

agile_geek17:12:17

So if you put that file in same dir as your project.clj it should find it

agile_geek17:12:14

I would give the file an extension tho or it will get confused with test/ directory

agile_geek17:12:27

i.e. call the file test.txt

agile_geek17:12:50

and use that in your string passed to the reader

roelofw17:12:37

I did : (with-open [rdr ( "test.txt")]

roelofw17:12:14

and

C:\Users\rwobb\Desktop\clojure\read-file>dir
 Volume in drive C has no label.
 Volume Serial Number is C0BB-040D

 Directory of C:\Users\rwobb\Desktop\clojure\read-file

19-12-2016  18:09    <DIR>          .
19-12-2016  18:09    <DIR>          ..
19-12-2016  17:50               110 .gitignore
19-12-2016  17:50               134 .hgignore
19-12-2016  18:09    <DIR>          .idea
19-12-2016  17:50               796 CHANGELOG.md
19-12-2016  17:50    <DIR>          doc
19-12-2016  17:50            11.433 LICENSE
19-12-2016  17:50               275 project.clj
19-12-2016  17:50             1.281 read-file.iml
19-12-2016  17:50               249 README.md
19-12-2016  17:50    <DIR>          resources
19-12-2016  17:50    <DIR>          src
19-12-2016  17:50    <DIR>          target
19-12-2016  17:50    <DIR>          test
19-12-2016  17:56                61 test.txt
               8 File(s)         14.339 bytes
               8 Dir(s)  757.095.403.520 bytes free

roelofw17:12:21

and still not found 😞

agile_geek17:12:08

Where is the with-open code? Which file?

roelofw17:12:13

in the first sentence of my question I stated : I did : (with-open [rdr ( "test.txt")]

agile_geek17:12:25

Where was that code executed? Where did you put the code above?

agile_geek17:12:45

Did you put that in core.clj or in the REPL or elsewhere?

delaguardo17:12:12

put the test.txt file in your resources directory and you will be able to read it with function.

roelofw17:12:15

oke, no, I made a file liked this on my cursive ide

roelofw17:12:35

(ns read-file.core)


(defn read-with-line-seq
  "read a file and display the contents woith line-seq"
  []
  (with-open [rdr ( "test.txt")]
    (println (line-seq rdr)))
 )

(read-with-line-seq) 

agile_geek17:12:46

@roelofw and you got file not found exception?

roelofw17:12:27

yes, then I see this as output :

Exception in thread "main" java.io.FileNotFoundException: test.txt (Het systeem kan het opgegeven bestand niet vinden), compiling:(C:\Users\rwobb\Desktop\clojure\read-file\src\read_file\core.clj:11:1)
	at clojure.lang.Compiler.load(Compiler.java:7391)
	at clojure.lang.Compiler.loadFile(Compiler.java:7317)
	at clojure.main$load_script.invokeStatic(main.clj:275)
	at clojure.main$script_opt.invokeStatic(main.clj:335)
	at clojure.main$script_opt.invoke(main.clj:330)
	at clojure.main$main.invokeStatic(main.clj:421)
	at clojure.main$main.doInvoke(main.clj:384)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.lang.Var.invoke(Var.java:379)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.io.FileNotFoundException: test.txt (Het systeem kan het opgegeven bestand niet vinden)
	at java.io.FileInputStream.open0(Native Method)
	at java.io.FileInputStream.open(FileInputStream.java:195)
	at java.io.FileInputStream.<init>(FileInputStream.java:138)
	at $fn__9520.invokeStatic(io.clj:229)
	at $fn__9520.invoke(io.clj:229)
	at $fn__9433$G__9426__9440.invoke(io.clj:69)
	at $fn__9532.invokeStatic(io.clj:258)
	at $fn__9532.invoke(io.clj:254)
	at $fn__9433$G__9426__9440.invoke(io.clj:69)
	at $fn__9494.invokeStatic(io.clj:165)
	at $fn__9494.invoke(io.clj:165)
	at $fn__9446$G__9422__9453.invoke(io.clj:69)
	at $reader.invokeStatic(io.clj:102)
	at $reader.doInvoke(io.clj:86)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at read_file.core$read_with_line_seq.invokeStatic(core.clj:7)
	at read_file.core$read_with_line_seq.invoke(core.clj:4)
	at read_file.core$eval12.invokeStatic(core.clj:11)
	at read_file.core$eval12.invoke(core.clj:11)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.load(Compiler.java:7379)
	... 16 more

Process finished with exit code 1
 

roelofw17:12:11

het systeem kan het opgegeven bestand niet vinden = cannot find file

dpsutton17:12:01

can you put it in your resources directory?

agile_geek17:12:33

As @dpsutton suggests you could put it in resources (you'll have to create it)

agile_geek17:12:47

and use instead of

agile_geek17:12:29

It will probably be not finding the file because you are running the compiled cod ein your target dir and the file is not getting copied to the target directory

agile_geek17:12:51

putting it in resources will fix that as resources get copied to target

roelofw17:12:29

oke, that worked

roelofw17:12:44

now a new error-message :

Exception in thread "main" java.lang.IllegalArgumentException: No matching field found: close for class java.net.URL, compiling:(C:\Users\rwobb\Desktop\clojure\read-file\src\read_file\core.clj:11:1)
	at clojure.lang.Compiler.load(Compiler.java:7391)
	at clojure.lang.Compiler.loadFile(Compiler.java:7317)
	at clojure.main$load_script.invokeStatic(main.clj:275)
	at clojure.main$script_opt.invokeStatic(main.clj:335)
	at clojure.main$script_opt.invoke(main.clj:330)
	at clojure.main$main.invokeStatic(main.clj:421)
	at clojure.main$main.doInvoke(main.clj:384)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.lang.Var.invoke(Var.java:379)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.IllegalArgumentException: No matching field found: close for class java.net.UR  

agile_geek17:12:33

That's because resource doesn'tr return a reader - jsut a url to the file

roelofw17:12:29

oke, so I have to make a reader with as argument the rdr variable ?

agile_geek17:12:36

Basically you can wrap your ( "test.txt") in a within the with-open

roelofw17:12:49

I found out already.

roelofw17:12:59

This works :

(defn read-with-line-seq
  "read a file and display the contents woith line-seq"
  []
  (with-open [rdr ( ( "test.txt"))]
       (println (line-seq rdr)))
  )

(read-with-line-seq) 

roelofw17:12:30

and gives this as output : ("ik ben regel 1 " "ik ben regel 2 " "en ik ben regel 3" )

agile_geek17:12:34

So you are printing the entire collection of lines so you can see them all. Try setting up a -main method that calls you (read-with-line-seq) function and run it from the terminal using lein run

roelofw17:12:39

moment, I have to make a main in project.clj : No :main namespace specified in project.clj.

roelofw17:12:22

@agile_geek then I see the same output : ("ik ben regel 1 " "ik ben regel 2 " "en ik ben regel 3" )

roelofw17:12:52

so the outputof line-seq is a seq

roelofw17:12:04

now I have to find out how I can make it work with mapv , I need somehow a map as input where rdr is a io object

agile_geek17:12:10

Right now change your function so that instead of printing the whole sequence you map println over each element in the sequence returned by lien-seq:

(map println (line-seq rdr))

agile_geek17:12:23

and call it using lien run

agile_geek17:12:28

not in the repl

roelofw17:12:51

Wierd, when I do what you said

(defn read-with-line-seq
  "read a file and display the contents woith line-seq"
  []
  (with-open [rdr ( ( "test.txt"))]
       (map println (line-seq rdr)))) 

roelofw17:12:05

then I do not see any output at all

agile_geek17:12:30

line-seq returns a lazy sequence

agile_geek17:12:44

when you map a function that has only side effects (like input and output) over a lazy sequence it has no effect as nothing forces the sequence to realise itself

agile_geek17:12:15

try changing map to mapv which forces the sequence to be realised and put into a vector

roelofw17:12:01

I did that already and see this as output :

"ik ben regel 1 "
"ik ben regel 2 "
"en ik ben regel 3"

roelofw17:12:40

with this as code :

(defn read-with-line-mapv
  "read a file and display the contents woith line-seq"
  []
  (with-open [rdr ( ( "test.txt"))]
    (mapv println (line-seq rdr)))
  ) 

agile_geek17:12:57

So read that link that @dominicm posted and see if you can see why?

agile_geek17:12:32

BTW if you call the -main function in the REPL it will throw a Stream closed exception

agile_geek18:12:55

that's cos the REPL forces the print of the first element of the sequence (the P in REPL stands for print) but when it loops back to print the next element the reader has closed.

agile_geek18:12:16

that's why I asked you to run it via lein run

roelofw18:12:26

In that page there is nothing about mapv but it seems that mapv is not lazy so the line-seq gets executed

agile_geek18:12:45

That's right

roelofw18:12:49

as you already said in your explanation

agile_geek18:12:04

mapv has to realise the whole sequence to put it in a vector

roelofw18:12:32

so 2 out of 3 already solved , Right ?

agile_geek18:12:45

Lazy sequences may seem like something you don't want to I/O but think about reading a huge file.

agile_geek18:12:14

If you realise the whole file in memory it will take a long time and you will probably run out of memory

roelofw18:12:27

big problem

agile_geek18:12:50

So once you understand lazy seq's they are very useful

agile_geek18:12:07

as long as you don't keep hold of the whole collection in memory

roelofw18:12:41

oke, then I have to find another way to read two responses in parallel and merge the 2 responses in one respons so I can parse them so I can display the right info

roelofw18:12:19

if I do it after each other the user has to wait long before he/she sees something on the screen

roelofw18:12:59

I think I have to rethink the whole idea I have used

roelofw18:12:45

Problem is that I have to have the ids first of the paintings before I can "download" the data and the image of each painting

roelofw18:12:39

so 3 request to three different urls where 2 depends on the outcome of the first respons

agile_geek18:12:46

You can jsut use mapv instead of map in your fn's for now

roelofw18:12:32

also for this one :

(defn do-both-in-parallel-front
  [ids]
  (let [paint-thread (future (pmap #(read-data-front-page (read-json-data %)) ids))
        image-thread (future (pmap #(read-image-url (read-image-data %)) ids))]
    (map merge @paint-thread @image-thread))) 

roelofw18:12:44

this one gives the right outcome at this moment

agile_geek18:12:06

Yeah not sure why you need futures

roelofw18:12:52

I also not but without it the code will not work

agile_geek18:12:00

That's probably cos of the lazyness. You may have to look at using doall

agile_geek18:12:13

although if you change your map merge to mapv merge that should work without futures

agile_geek18:12:31

(defn do-both-in-parallel-front
  [ids]
  (let [paintings (pmap #(read-data-front-page (read-json-data %)) ids)
        images (pmap #(read-image-url (read-image-data %)) ids)]
    (mapv merge paintings images))) 

roelofw18:12:40

moment, I have to reboot my windows computer ,

roelofw18:12:46

@agile_geek that code works well

roelofw18:12:03

I see the front page without any error messages

roelofw18:12:42

Can we do the same with this function :

(defn do-both-in-parallel-detail
  [ids]
  (let [paint-thread (future (pmap #(read-data-detail-page (read-json-data %)) ids))
        image-thread (future (pmap #(read-image-url (read-image-data %)) ids))]
    (mapv merge @paint-thread @image-thread))) 

agile_geek18:12:53

There's no need for separate threads in futures as the pmap spins up it's own threads to make calls in parallel

agile_geek18:12:54

The mapv is required as pmap is semi-lazy so you have to force it to realise similar to map in that read-file example

roelofw18:12:51

oke, I get the feeling that my code is not optimal. We have to use "tricks" to make things work

agile_geek18:12:13

You could probably use map instead of mapv depending on how your page displays the data. i.e. if the templating functions always consume the whole sequence.

agile_geek18:12:37

I am not sure what Selmer does

roelofw18:12:17

I also do not know it

roelofw18:12:36

but I mean more the code for reading the data

roelofw18:12:49

and put everything in one response

agile_geek18:12:24

Nothing wrong with your code for that really. It would be good if you could make one call to the api to fetch the whole list of paintings with their names, etc. but that's the api you are calling not your code

agile_geek18:12:36

There are other ways of fetching the images and painting details and merging them together but not sure they are much better, just different

agile_geek18:12:06

Anyway I'm heading home now

roelofw18:12:01

have a save ride back

roelofw18:12:05

and thanks

roelofw18:12:30

Everythings works well now

roelofw18:12:47

Time to make a nice layout for the detail page

roelofw18:12:12

and then the last problem/challenge. Making pagination for the front-page

neurogoo20:12:00

I am trying to use ring-transit, but it doesn't seem to convert the response to transit form. Is there anyway to debug why this is happening?

neurogoo20:12:45

Response that I am trying to send is something like ({:songs [{:path "song1.mp3", :id 0, :track-number "2", :album "Album1"} {:path "song2.mp3", :title "Song 1", :id 1, :track-number "9", :album "Album1})

roelofw20:12:39

which encoding do you use

roelofw20:12:59

we can better help you when we see actual code

neurogoo20:12:55

You mean character encoding? I am not setting anything for that so it is what it is by default

neurogoo20:12:46

I have not yet put this code online as it really doesn't do that much yet ^^'

roelofw21:12:28

but every little bit code can help

roelofw21:12:53

you can put it here or in something like repheap

neurogoo21:12:58

okay, never heard about this place before

neurogoo21:12:21

so first part has the routes definitions and under that I copy pasted relevant functions from my other code files

neurogoo21:12:53

and I am trying that /files route

seancorfield21:12:14

@neurogoo You are passing handler as the “options” argument in your wrap-middleware function. The -> macro already passes handler as the first argument. You want (wrap-transit-response {}) — replace {} with whatever specific options you want.

seancorfield21:12:00

Also you seem to have a typo — /daa in your routes? If you correct that (to /data) then you can remove the explicit (GET “/song/:id/data” …) route.

neurogoo21:12:31

No, that is not typo 😄 It was just temp route to tryout that context thing. But thanks for the first tip! I will fix that see if that helps

neurogoo21:12:10

hmmm that unfortunately didn't really change anything

mlev21:12:36

This is for a Luminus app.

seancorfield21:12:43

@mlev That code will run when you load that namespace, before any app code runs. I doubt that’s what you want? Shouldn’t that be in a function that gets invoked?

mlev21:12:29

@seancorfield , makes sense to me. Within the Luminus app I have a home.html template file with the following code:

{% extends "base.html" %}
{% block content %}
<div id="content" ></div>		    
{% endblock %}
and a base.html template file with the following code section:
<!-- scripts -->
    {% script "/assets/jquery/jquery.min.js" %}
    {% script "/assets/tether/dist/js/tether.min.js" %}
    {% script "/assets/bootstrap/js/bootstrap.min.js" %}

    <script type="text/javascript">
      var context = "{{servlet-context}}";
    </script>
    {% script "/js/app.js" %}
    {% block page-scripts %}
    {% endblock %}
I may be missing something elementary here, but I figured others may be running into a similar issue 🙂

mlev21:12:13

Perhaps I am looking at the wrong port? I am typing LocalHost:3000 into my browser. Here is the actual output from lein run though:

-=[guestbook started successfully using the development profile]=-
2016-12-19 16:10:00,672 [main] INFO  luminus.http-server - starting HTTP server on port 3000
2016-12-19 16:10:00,750 [main] INFO  org.xnio - XNIO version 3.3.6.Final
2016-12-19 16:10:00,938 [main] INFO  org.projectodd.wunderboss.web.Web - Registered web context /
2016-12-19 16:10:00,953 [main] INFO  luminus.repl-server - starting nREPL server on port 7000
2016-12-19 16:10:00,953 [main] INFO  guestbook.core - #'guestbook.config/env started
2016-12-19 16:10:00,969 [main] INFO  guestbook.core - #'guestbook.db.core/*db* started
2016-12-19 16:10:00,969 [main] INFO  guestbook.core - #'guestbook.handler/init-app started
2016-12-19 16:10:00,969 [main] INFO  guestbook.core - #'guestbook.core/http-server started
2016-12-19 16:10:00,969 [main] INFO  guestbook.core - #'guestbook.core/repl-server started

gdeer8121:12:15

the fact that you're seeing the other tabs means you can rule that out

gdeer8121:12:38

can you inspect the page and see if you're getting any errors in your browser?

mlev21:12:26

Thanks, @gdeer81 , always appreciate your help as well. Here is the error screen:

2 errors:   Failed to load resource: the server responded with a status of 404 (Not Found)

gdeer8121:12:54

@mlev did you update your project.clj file to tell cljsbuild where to output the compilation to?

mlev21:12:58

@gdeer81 , my project.clj file contains the following:

:cljsbuild
  {:builds {:app {:source-paths ["src/cljs"]
                  :compiler {:output-to "target/cljsbuild/public.js/app.js"
                             :output-dir "target/cljsbuild/public/js/out"
                             :main "guestbook.core"
                             :asset-path "/js/out"
                             :optimizations :none
                             :source-map true
                             :pretty-print true}}}}
  :clean-targets
  ^{:protect false}
  [:target-path
   [:cljsbuild :builds :app :compiler :output-dir]
   [:cljsbuild :builds :app :compiler :output-to]]

gdeer8122:12:09

@mlev and what about your :resource-paths key ?

mlev22:12:13

The main keys under my :defproject are:

:source-paths ["src/clj"]

  :resource-paths ["resources" "target/cljsbuild"]

  :target-path "target/%s/"
and there are a few additional keys under :defproject:
:profiles

  {:uberjar {:omit-source true

             :aot :all

             :uberjar-name "guestbook.jar"

             :source-paths ["env/prod/clj"]

             :resource-paths ["env/prod/resources"]}



   :dev           [:project/dev :profiles/dev]

   :test          [:project/dev :project/test :profiles/test]



   :project/dev  {:dependencies [[prone "1.1.4"]

                                 [ring/ring-mock "0.3.0"]

                                 [ring/ring-devel "1.5.0"]

                                 [pjstadig/humane-test-output "0.8.1"]]

                  :plugins      [[com.jakemccrary/lein-test-refresh "0.14.0"]]

                  

                  :source-paths ["env/dev/clj" "test/clj"]

                  :resource-paths ["env/dev/resources"]

                  :repl-options {:init-ns user}

                  :injections [(require 'pjstadig.humane-test-output)

                               (pjstadig.humane-test-output/activate!)]}

   :project/test {:resource-paths ["env/test/resources"]}

gdeer8122:12:11

@mlev so when you did lein cljsbuild once did you get any errors? you shouldn't be getting a 404 on app.js if the compiler did its job. Is app.js in your output directory?

mlev22:12:26

@gdeer81 , I reran the lein cljsbuild once, received the message:

Compiling ClojureScript...
2016-12-19 17:11:04,206 [main] DEBUG org.jboss.logging - Logging Provider: org.jboss.logging.Slf4jLoggerProvider
Then reran lein run and can still see both tabs but no "Hello, Reagent."

Lone Ranger22:12:56

pardon me good folks, how would I set up my lein project.clj to make (use 'clojure.java.jdbc) not crash when I use lein run?

:dependencies [[org.clojure/clojure "1.8.0"],
                 [clojure.java.db]]
does not seem to work 😞

noisesmith22:12:35

that should be clojure.java.jdbc and it needs a version string

Lone Ranger22:12:48

is there a way to do "latest"?

noisesmith22:12:54

yes, and don't

Lone Ranger22:12:13

hahaha! very well! any recommendations?

gdeer8122:12:09

@mlev the code snippet you posted above said that it was supposed to say "Hello world"

gdeer8122:12:47

@mlev are you working on the section "Build the UI with Reagent" ?

gdeer8122:12:06

I'm looking at the Safari online version so I don't have page numbers

Lone Ranger22:12:09

ah, yes, thank you 😄

Lone Ranger22:12:16

I suppose I could've googled that 😞

Lone Ranger22:12:24

but you're all so friendly and helpful!!

noisesmith22:12:45

goomba there's a lein plugin called lein ancient that can help you find out about newer versions of libraries, but I don't recommend just using "latest version always"

neurogoo22:12:06

my problem was finally solved by explicitly setting header Content-Type to "applicaiotn/transit+json" -_- And I have troubleshooted this so long....

noisesmith22:12:25

generally you'll find the latest release via maven or clojars too

gdeer8122:12:19

@mlev the code you posted was from the previous section, your code should look totally different now

noisesmith22:12:20

another fun trick is seeing what version everybody open source is using https://crossclj.info/

mlev22:12:52

@gdeer81 , I apologize, I am trying to display the the Reagent version based on the following code in my core.cljs file:

(ns guestbook.core
  (:require [reagent.core :as reagent :refer [atom]]))

(defn home []
  [:h2 "Hello, Reagent"])

(reagent/render
 [home]
 (.getElementById js/document "content"))

mlev22:12:24

You are 100% correct, the "Hello, World" portion was from the previous section.

gdeer8122:12:25

@mlev you might have to just push your project to github to make it easier to review all the code to make sure it matches what the book is expecting. I feel like I'm debugging blind

gdeer8122:12:40

@mlev but first, did you look in your target folder to see if it compiled app.js?

mlev22:12:07

@gdeer81 , github may be the way to go on this one, true. Here is the code in my C:\...\guestbook\target\cljsbuild\public.js\app.js file:

var CLOSURE_UNCOMPILED_DEFINES = null;
if(typeof goog == "undefined") document.write('<script src="/js/out/goog/base.js"></script>');
document.write('<script src="/js/out/cljs_deps.js"></script>');
document.write('<script>if (typeof goog == "undefined") console.warn("ClojureScript could not load :main, did you forget to specify :asset-path?");</script>');
document.write('<script>goog.require("guestbook.core");</script>');