Fork me on GitHub
#beginners
<
2018-08-23
>
seancorfield00:08:37

@its.ramzi You have it running locally (without building a WAR)?

seancorfield00:08:39

(Reagent is a ClojureScript GUI library so I'm confused by your comment -- the error you are getting is from running a backend Clojure program)

Ramzi01:08:25

@seancorfield Check out a new Reagent project by doing lein new reagent my-app. Then launch my-app by issuing lein figwheel. Go to localhost:3449. You'll see the default app, and how changing the source causes a hot deployment. But if you save this page, you get extra figwheel stuff in the HTML which isn't wanted for production.

dpsutton01:08:25

What do you mean save? Figwheel injects stuff into the page during development but that shouldn't affect anything

Ramzi01:08:57

I mean hitting Control S in your web browser to save a local copy of the HTML and the other files like CSS, JS, and images that make up the site.

Ramzi01:08:43

Otherwise, I do not know how to produce a static HTML page for production.

noisesmith01:08:12

maybe save the html once, and then edit it as needed, but saving the page shouldn't be part of your deploy process, because yeah there's likely a lot of stuff in there for figwheel that shouldn't apply to your prod code

noisesmith01:08:48

also saving and using the page that has been rendered by reagent will break reagent in most cases - it wants an empty dom node to inject its stuff into

noisesmith01:08:00

if you save the page it saves what reagent wants to produce itself

Ramzi01:08:10

If I make a simple page with one input that has an on-change alert, and then I save that page, and I go to that file on my local harddrive, I get the alert. But when I drag that page along with the compiled app.js to the web folder of a Netbeans Java Web project, I cannot get the alert to trigger. Maybe some paths get broken. That's why I would like to work with someone to help me nail down the process of developing in Reagent and then moving to production.

noisesmith01:08:52

your best bet is probably to get the "web development with clojure" book and follow that

Ramzi01:08:53

Right, it presumes there is a div called app which it loads into, and there needs to be a way to trigger an initialization function, but I don't know how to do that.

Ramzi01:08:22

i think all of these web development in clojure books are assuming you're building a client side app that connects to no database.

noisesmith01:08:14

the book I just recommended has chapters covering db integration, it won't happen the way you have in mind, but it will be easier to learn what it does and adapt than it is to figure all this out from first principles

Ramzi01:08:18

why is it so hard for me to go from a clean pull of Reagent to deploying it in prod mode?

seancorfield03:08:28

@its.ramzi How did you create the WAR file?

seancorfield03:08:33

I don't see how to do that directly from the basic Reagent template... it talks about creating an uberjar but not a WAR...

Ramzi03:08:33

@seancorfield A teammate did it and I was unable to replicate the steps. It involved putting something in the project.clj file to import the uberwar plugin and make it a build type, or something

Ramzi03:08:48

But when I tried to replicate that on my computer, I got a filenotfoundexception and was unable to make a WAR even.

seancorfield03:08:27

@its.ramzi You can make a standalone JAR file from the base project -- lein do clean, uberjar -- and that will create two JAR files in target, one of which can be run directly with java -jar target/reapp.jar (or whatever you called the project). That will start a Jetty web server on port 3000 running the app.

Ramzi03:08:16

It can't be that easy. Let me log into my work computer to try.

Ramzi03:08:47

I'm wondering, still, is there an easy way to extract the static html and minified app.js

seancorfield03:08:08

No, that's not how you build web apps.

seancorfield03:08:01

$  lein new reagent reapp
$  cd reapp/
$  lein do clean, uberjar
$  java -jar target/reapp.jar
that's all I did to get the standalone app built and running

Ramzi03:08:18

Im trying one sec thx

Ramzi03:08:38

i got a subprocess failed

Ramzi03:08:48

so i am thinking that i corrupted my project somehow and should start clean

Ramzi03:08:08

What do you mean that is not how you build webapps?

Ramzi03:08:24

What if I wanted to deploy on Tomcat? Rather than a Jetty server?

seancorfield03:08:53

You can't just save a generated HTML page and expect to be able to serve it up with a live backend app somehow.

seancorfield03:08:14

Why would you want to deploy on a Servlet container, rather than the embedded Jetty server? In general, Clojure apps don't tend to be deployed as Servlets. Most people just run them with an embedded server -- Jetty or http-kit.

Ramzi03:08:30

I didnt want the backend at that point. I just want inputs with javascript. Then I would do an Ajax call to connect to a java backend

seancorfield03:08:25

Well, the application templates tend to be fairly opinionated about how they work/deploy...

Ramzi03:08:39

In my head, my knowledge of webservers probably couples too many things that are actually decoupled. Like, I want to connect to java/hibernate/postgres. And I only know how to do that with JSPs and Tomcat.

seancorfield03:08:12

So you just want a ClojureScript front end? You don't want a Clojure back end?

Ramzi03:08:29

I thought that was a contradiction in terms

Ramzi03:08:45

My customer already has an Ember app which has a postgres database. None of the developers like Ember

Ramzi03:08:52

So I wanted to remake the front end in Clojurescript

seancorfield03:08:49

You can certainly do that.

seancorfield03:08:37

The ClojureScript build tools can be configured to produce a single HTML file and the compiled-to-JS files that would need.

seancorfield03:08:08

And you can write your ClojureScript to interact with REST back end (which is what I assume you already have?)

Ramzi03:08:54

No, Im still getting this "run figwheel" garbage when i view source

Ramzi03:08:12

I think the project has both SOAP and REST calls but Im not sure

seancorfield03:08:24

Ignore view source. That's not how you get the HTML/JS for the app.

noisesmith03:08:26

if you use figwheel to serve your page, it will contain figwheel stuff

Ramzi03:08:37

i didnt. i did the java jar deploy

seancorfield03:08:40

Part of the problem with starting from a template is that it includes a huge amount of machinery -- so if you want to deviate from how that is assumed to be used, you'll have to understand a lot of moving parts.

Ramzi03:08:04

How can I get the HTML/JS for the app?

seancorfield03:08:13

If you only want to write a Reagent-based front end for a REST app, don't start from the template.

seancorfield03:08:30

Read about ClojureScript build tools -- they can generate the HTML etc to disk directly.

Ramzi03:08:31

does it matter if it's soap or rest?

seancorfield03:08:39

Yes, it matters a lot.

Ramzi03:08:53

we have a wsdl, but i think there are also some rest calls

Ramzi03:08:56

why does this matter

seancorfield03:08:32

SOAP is horrible to work with 😞

Ramzi03:08:03

So if I use the inspector and get the live html, thats one way i can get the html

seancorfield03:08:14

No. Don't do that.

seancorfield03:08:25

We keep telling you not to do that.

seancorfield03:08:04

The cljs build tools can generate the files you need directly to disk. Dev/production versions are controlled from the cljs build tools.

Ramzi03:08:22

the cljs build tools i saw only made the minified app.js

Ramzi03:08:29

but no index.html

noisesmith03:08:58

the cljs build tool should not be generating your index.html; typically you write an index.html to host your cljs app

Ramzi03:08:52

thats really interesting. this is starting to make more sense now. thanks.

seancorfield03:08:05

(but it's a trivial HTML file since everything is dynamically added to the DOM as the app starts up)

👍 4
noisesmith03:08:21

you could copy the index figwheel made for you as a start, but maintain it as its own thing

seancorfield03:08:26

@its.ramzi If you do lein new mies miesapp you'll get basic HTML files for dev and release. Mies has no Clojure aspect so it's a much smaller, cleaner project to start with.

seancorfield03:08:49

(and it'll be a good place to learn about plain ol' cljs for a front end)

Ramzi03:08:58

so i should just drop all thoughts of Tomcat?

seancorfield03:08:31

Well, you're not going to use a Clojure back end right? So you don't need Tomcat.

seancorfield03:08:38

(or Jetty or whatever)

seancorfield03:08:55

You just want a cljs front end that calls your existing back end yes?

Ramzi03:08:55

Does this mean I need two servers? A GUI server and a web server?

seancorfield03:08:41

How is your current Ember-based GUI served up? That's exactly how you'll deploy your new cljs GUI.

seancorfield03:08:08

Is your Ember-based GUI initial HTML rendered from a .html file or dynamically from inside the Java app?

Ramzi03:08:40

I thought i would serve up the HTML and JS in tomcat that way I can make Ajax calls and avoid COR errors.

Ramzi03:08:03

I dont know how to write to postgres just with clojurescript

Ramzi03:08:24

maybe i do want to replace the back end?

Ramzi03:08:47

at least as an exercise, i need to understand how to go from a web input to getting a row in postgres

seancorfield03:08:07

You already have a back end for dealing with the database tho'...

seancorfield03:08:17

You said you wanted to keep that.

Ramzi03:08:18

That deals with ember models and stuff?

seancorfield03:08:29

Ember is front end, not back end.

Ramzi03:08:39

No one understands that. I want to remake the back end logic but keep the Java objects with the hibernate annotations

seancorfield03:08:59

I have no idea what you mean.

Ramzi03:08:02

Somehow our ember app is getting things in a postgres database

seancorfield03:08:15

Ember is a JS framework. It is purely front end.

Ramzi03:08:41

it is deployed in wildfly

seancorfield03:08:54

It is communicating with your existing Java/Hibernate/Postgres back end app which does the database stuff.

Ramzi03:08:06

so how does the front end, ember, communicate with the back end, wildfly?

seancorfield03:08:41

Most likely ajax calls to a REST API I expect -- which is why you need to find that out.

Ramzi03:08:53

i know we have multiple wsdl files

Ramzi03:08:01

And the customer wants to go to pure REST some day

Ramzi03:08:13

and i found a program that will make REST services out of a postgres database

seancorfield03:08:14

Your new cljs front end can work just like your Ember app, making the same sort of ajax calls to the (existing) back end.

Ramzi03:08:34

But what if I wanted to expand the backend business logic?

Ramzi03:08:43

oh, that's java then, not ember

Ramzi03:08:46

you're right

Ramzi03:08:50

im so confused.

Ramzi03:08:09

so all i am doing is replacing the shitty ember framework with the awesome clojurescript GUI

seancorfield03:08:19

Basically, yeah.

Ramzi03:08:24

wont i get COR errors

seancorfield03:08:01

Like I said, you'd serve up the HTML and compiled-to-JS files the exact same way that your current HTML and Ember.js files are served up.

Ramzi03:08:18

They are served up as a .ear in Wildfly

seancorfield03:08:01

So you'll need to talk to the team that maintains the build process that produces the the EAR file.

Ramzi03:08:24

we have a command that does it

seancorfield03:08:26

Since the build process would need to include your cljs-based HTML/JS files instead of the Ember ones.

Ramzi03:08:36

hmmm.....

Ramzi03:08:48

the build process is maven

seancorfield03:08:49

You're going to need to learn a lot more about how your current build process works.

seancorfield03:08:30

This sort of complex, ossified build process and application structure is a lot of what more Clojure/Script programmers want to avoid 🙂

Ramzi03:08:00

how should i go from here

Ramzi03:08:04

i have a postgres database

Ramzi03:08:15

i need to modify the build

Ramzi03:08:25

to include my new index.html and app.js

Ramzi03:08:53

and then upload that as a .ear to wildfly

seancorfield03:08:12

I doubt anyone here can help you with anything to do with your company's build process ¯\(ツ)

😁 4
Ramzi03:08:22

then my ajax inputs will be able to talk to the backend without COR

seancorfield03:08:46

But, yeah, sounds like you have a goal.

Ramzi03:08:54

what do you think of the idea of just doing a total port

Ramzi03:08:06

so we can have new db tables so long as all the existing data is migrated

seancorfield03:08:24

How much Java etc does your existing app have?

Ramzi03:08:35

how would i go about having a clojure back end that talks to postgres? would i use hibernate still?

seancorfield03:08:40

Bear in mind that Clojure apps don't use Hibernate.

seancorfield03:08:53

There are no objects in Clojure so you don't need an ORM.

Ramzi03:08:04

omg i have no idea how this thing is so huge. we have like 1400 js components and 400 java files, but only like 30 views. which is why i want to just scratch it and rewrite it.

Ramzi03:08:18

so how do i write to postgres through clojure

Ramzi03:08:28

i guess that would be a total prototype to get me started

Ramzi03:08:34

an input all the way to a db row

Ramzi03:08:17

then i need to work with SQL types

Ramzi03:08:23

which using hibernate avoided

noisesmith03:08:41

as I mentioned earlier, this book covers everything you would need, with reasonable choices for pretty much everything https://pragprog.com/book/dswdcloj2/web-development-with-clojure-second-edition

Ramzi03:08:49

and this commits us to postgres, rather than being able to change a db with a configuration change in the hibernate.cfg.xml

Ramzi03:08:06

i think i'll buy it.

noisesmith03:08:07

in clojure we avoid sql types by using a lib that hands us normal data

seancorfield03:08:17

Unless you are using Postgres-specific SQL, you can switch DBs pretty easily.

Ramzi03:08:26

so does the book deploy to a local web server, not a cloud server or something?

Ramzi03:08:50

we need to have the program run off a centralized server for now, but move to the cloud in the future

noisesmith04:08:21

it has a chapter on deployment

seancorfield04:08:26

If you're replacing your whole front end / back end app, you'll probably also switch to a different server model 🙂

Ramzi04:08:46

but, like, reagent had deployment instructions that used Heroku

Ramzi04:08:52

or, ive seen deploying to github

Ramzi04:08:13

But this is a confidential government app. So we would need to use AWS government. Not Heroku.

Ramzi04:08:20

And of course we couldnt just publish to github

seancorfield04:08:24

We used to deploy web apps to large Tomcat instances. Now we deploy each small web app as a self-contained (uber) JAR that runs either Jetty or http-kit as a standalone server.

Ramzi04:08:42

Who is "we"? Your company or the community?

seancorfield04:08:52

We = the company I work for.

Ramzi04:08:09

When I use Java HTTPServer it crashes over night

Ramzi04:08:16

Jetty is stable enough not to crash?

seancorfield04:08:47

We run on http-kit in production but we've also found Jetty to be very stable as well.

Ramzi04:08:24

so i guess tomorrow i begin prototyping connecting clojurescript to clojure and postgres

seancorfield04:08:27

(we can actually select the server at application start up)

Ramzi04:08:35

then i can do the rapid development of remaking the app

seancorfield04:08:55

Since you're a beginner -- with Clojure/Script as well as a whole bunch of web app stack concepts, it seems -- I think you'll struggle trying to replace so much existing stuff but it will be a great learning experience.

seancorfield04:08:20

Working with Clojure is radically different to working with Java.

Ramzi04:08:24

i think, if i had a prototype that goes from input to a db row, then i can replicate the whole software fast

Ramzi04:08:39

ive done a bunch of 4Clojure problems

Ramzi04:08:56

but i already remade the gui so fast in figwheel

Ramzi04:08:09

i just didnt understand how to deploy with the java jar, simple thing you showed me

noisesmith04:08:59

I've had good luck with using the jsvc program to run the jar as a service

Ramzi04:08:25

hey thanks for all your help. it's past midnight here

seancorfield04:08:48

(Since you mentioned govt app, I'd assume DC area?)

seancorfield04:08:27

You'll be back online before us West Coast types...

Ramzi04:08:36

Maybe I'll talk to you tomorrow?

Ramzi04:08:43

Are you usually on here helping noobs?

seancorfield04:08:52

Yeah, when I'm awake 🙂

Ramzi04:08:06

so, everyone on the team hates ember

Ramzi04:08:13

and half the team wants to rebuild in angular

Ramzi04:08:19

but i want to rebuild in clojure

seancorfield04:08:20

I know lots of people who hate Ember 🙂

Ramzi04:08:30

so we're racing to produce a prototype

seancorfield04:08:46

At work, we decided to go with React.js over Angular, but we have a pure JS front end and a pure Clojure back end.

Ramzi04:08:53

but he didnt understand how to connect Angular to the backend. and i didnt understand how to connect Clojurescript to the backend.

Ramzi04:08:44

how do you make ajax calls in pure JS

Ramzi04:08:53

i thought you need to import jquery

Ramzi04:08:25

Someone made that for me. so thats how you can do ajax in clojurescript

Ramzi04:08:28

does he use jquery?

seancorfield04:08:10

We have REST APIs on the back end (Clojure), called via ajax from React.js etc on the front end. I don't know what library our front end team chose for the REST call stuff. I can ask them tomorrow.

Ramzi04:08:35

so Reagent is a wrapper to React

Ramzi04:08:40

and i love developing in it

seancorfield04:08:50

For one of our new apps, the Clojure back end exposes a GraphQL API but I haven't looked at the code much.

Ramzi04:08:07

okay have a goodnight

grounded_sage09:08:15

how do I run a function just once. Regardless of being called by Clojure of Closure Compiler?

grounded_sage09:08:59

I have a macro that runs twice because it is called for SSR and when compiling the JS. I just want to run it once.

grounded_sage09:08:47

It is a side effecting macro too.

jaihindhreddy-duplicate10:08:22

^ As a fellow beginner (take this with a block of salt 🙂 ) the first thing that comes to mind is to have the function put the action in a channel and make a go block pick one value from the channel and perform the actual side effect. But I'm sure there's a much better (simpler) way to do it.

moxaj11:08:39

@grounded_sage the simplest (non)answer would be to eliminate the side effect - I don't think that's a good practice generally

grounded_sage12:08:03

@moxaj it's image/file manipulation which is impossible to avoid haha.

moxaj12:08:30

and you necessarily have to do that during macroexpansion time?

grounded_sage12:08:10

yea haha. It's a funny one. I think I have an idea to cancel the second run of it by putting the results in a map and checking on the second call if it has already been done.

veddha12:08:08

can someone tell how to use media query css at fulcro?

sundarj12:08:19

also there's a #fulcro channel you can ask questions in, in future

veddha13:08:53

thank u very much

grounded_sage12:08:37

My assumptions were correct. I have a defonce collecting the directories and files recursively. Then I cross check that when running the macro to see if it needs to be generating. Adding it to the map when I generate it. This lets me generate it just once regardless if the macro is called just from clojure, just from clojurescript compilation or both.

agigao12:08:26

Hello Clojurians, I’ve been playing with yada lately and decided to go “simple” route, build on my own instead of using edge. So, right now have a resource defined, route created and trying to fire-up aleph server, which I’m having tough time to achieve.

noisesmith17:08:09

@grounded_sage why a macro instead of a top level function call?

grounded_sage03:08:26

The the macro is used in a cljc file. Called with a map of data then returns hiccup syntax that is used to generate SSR HTML and React Component. Whilst simultaneously fetching file metadata and generating new files linked to in the HTML.

Michael Stokley19:08:03

i'm having some trouble using the library algo. in my project.clj:

:dependencies [[org.clojure/clojure "1.9.0-alpha17"]
                 [org.clojure/algo.generic "0.1.3"]]
; in my source code:
(ns rules-engine.core
  (:require
            [clojure.algo.generic.functor :as gf]))

Michael Stokley19:08:11

i've run and re-run lein -U run but it keeps telling me it can't find it:

Could not locate clojure/algo/generic/functor__init.class or
   clojure/algo/generic/functor.clj on classpath.

Michael Stokley19:08:44

this seems like the right syntax. anyone know what i'm missing?

dpsutton19:08:06

just a preliminary question, did you restart your repl when you added the new dependency?

Michael Stokley19:08:44

i'll try that now

dpsutton19:08:56

give that a shot. you'll need to download the dep and then make sure its on your classpath. restarting the repl will most likely do that for you 🙂

Michael Stokley19:08:57

no good... i restarted the repl and re-ran lein deps

Michael Stokley19:08:14

importing third party libs has always been a stumbling block for me in clojure

dpsutton19:08:23

are you using lein?

hiredman19:08:16

what does lein classpath say? does it include algo.generic?

Michael Stokley19:08:05

12:16 $ lein classpath
/home/michael/rules-engine/test:/home/michael/rules-engine/src:/home/michael/rules-engine/dev-resources:/home/michael/rules-engine/resources:/home/michael/rules-engine/target/default/classes:/home/michael/.m2/repository/tigris/tigris/0.1.1/tigris-0.1.1.jar:/home/michael/.m2/repository/org/clojure/tools.nrepl/0.2.12/tools.nrepl-0.2.12.jar:/home/michael/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.9.0/jackson-dataformat-smile-2.9.0.jar:/home/michael/.m2/repository/org/clojure/algo.generic/0.1.3/algo.generic-0.1.3.jar:/home/michael/.m2/repository/clojure-complete/clojure-complete/0.2.4/clojure-complete-0.2.4.jar:/home/michael/.m2/repository/org/clojure/clojure/1.9.0-alpha17/clojure-1.9.0-alpha17.jar:/home/michael/.m2/repository/org/clojure/core.specs.alpha/0.1.10/core.specs.alpha-0.1.10.jar:/home/michael/.m2/repository/cheshire/cheshire/5.8.0/cheshire-5.8.0.jar:/home/michael/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.9.0/jackson-core-2.9.0.jar:/home/michael/.m2/repository/org/clojure/spec.alpha/0.1.123/spec.alpha-0.1.123.jar:/home/michael/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/2.9.0/jackson-dataformat-cbor-2.9.0.jar

Michael Stokley19:08:41

oh! restarting emacs seems to have done it

Michael Stokley19:08:54

so maybe that repl restart didn't take

dpsutton19:08:02

that shouldn't matter. how did you restart the repl?

hiredman19:08:08

I doubt it was a repl restart

hiredman19:08:18

my guess is you never saved project.clj after making changes

Michael Stokley19:08:57

in spacemacs- , s X which is cider-restart

hiredman19:08:07

or I have also seen people have a copy of project.clj somewhere else and edit the wrong copy

rcustodio19:08:55

I got a beginner question.... how does clojure promise differs from the java concurrent future?? Can someone tell??

hiredman20:08:01

java.util.concurrent.Furture is an interface with many different implementations with different behaviors

hiredman20:08:17

a clojure promise is a concrete implementation

hiredman20:08:26

Future as an interface is largely about supply something that represents a value that may be supplied at a later date (it has some other methods like isDone, and isCancelled, that imply something about the execution model)

hiredman20:08:14

a clojure promise also represents a value to be supplied later, but gives both a way to represent the value to be supplied later, and a way to supply it, and a promise doesn't have methods to "cancel" it, because it doesn't assume a promise's delivery is tied to some concurrent task

👍 4