Fork me on GitHub
#beginners
<
2022-09-04
>
Noyal Jose12:09:38

I've learned the basics of clojure and now I'm going through the documentation of http-kit to understand how clojure does web requests and responses

Noyal Jose12:09:05

I'm a bit over whelmed 😓

lsenjov12:09:07

Ring is the de facto library/abstraction for clojure rest servers

Noyal Jose13:09:54

hey thanks for the suggestion

Noyal Jose13:09:03

lemme check it out

Damian Koncewicz17:09:30

I was making simple to-do app with friend, so it is basic's with Reagent and im exhausted. 😄 I know what you mean, but never give up 😉

walterl18:09:30

If you want a more "batteries included" kind of approach, you can check out https://kit-clj.github.io/ or https://biffweb.com/

walterl18:09:46

(I haven't used Biff yet, but it looks really nice.)

Michaël Salihi18:09:29

I recommend to start simple. you can play with this basic example Babashka + http-kit + basic routing https://github.com/prestancedesign/babashka-htmx-todoapp

walterl20:09:13

"Simple" is an interesting term in this context. I share @U03VC5CUADR's feeling of being overwhelmed when starting a simple web app. I've been using Clojure for a couple of years now, and while I haven't started a ton of web apps, it's certainly overwhelming to get started each time. Which server? Which router? What middleware do I need? Which templating language? How do I coordinate and configure each of those to work together? Of course one learns the answers over time, but 1. it's inefficient to have to remember and type out all of those answers each time, and 2. why do I need to care about any of that, when all I want is to serve up some HTML? I understand the community's arguments against web frameworks, but it still leaves newcomers with that feeling of dread, having to become familiar with all of the various components (as good as they may be) before being able to do anything. I'm working on a solution for a "dissolving framwork" which allows you take over parts (or all) of the default web app setup, as and when you need/want to. This (excessively Spartan) demo task list app is 25 lines of Clojure (sans HTML template):

(ns walterl.botter-test
  (:require [botter :as b]))

(defonce todos (atom []))

(defn- list-items
  [_request & [templ-data]]
  (b/render-template "list.html" (assoc templ-data :items @todos)))

(defn- add-item
  [{{:keys [text]} :params, :as _request}]
  (swap! todos #(conj % {:id (str (random-uuid)), :text text}))
  (list-items nil {:flash (format "Added item: \"%s\"" text)}))

(defn- toggle-item
  [{{:keys [id]} :params, :as _request}]
  (swap! todos
         (fn [items]
           (map #(cond-> % (= (:id %) id) (update :done? not)) items)))
  (list-items nil {:flash (format "Item toggled.")}))

(def routes
  [["/" {:get list-items
         :post add-item}]
   ["/toggle" {:post toggle-item}]])

Noyal Jose23:09:52

I'm completely new to making any kind of web related programming. I just know how requests and responses work since I started out learning web app exploitation. So idk how a web server function to start with.

Noyal Jose23:09:56

Can someone suggest a resource which teach how a web server app works (in clojure).

Noyal Jose23:09:24

ik using libraries instead of frameworks is daunting to learn for new comers I don't mind that as long as the resources are in-depth and explains all the details

Chase15:09:54

I've also found this yt channel beginner friendly: https://youtube.com/c/onthecodeagain

Chase15:09:24

I agree that the best bet is to start with Ring. Explore that library and go from there. It basically handles web requests and responses (using clojure maps for both). So it turns a web request into a clojure map, you do what you want with that, then you return a response (to the client’s browser for example) as a clojure map as well. It handles receiving and returning those maps into the relevant http requests and responses.

Chase16:09:24

This guy is also pretty beginner friendly: https://youtu.be/3AWXM8CN6FA

Noyal Jose06:09:20

Thanks a lot @U9J50BY4C i'll check it out

Elior Digmi12:09:19

Hi everyone, I'm working with IntelliJ IDEA as my editor, and I tried to install LSP Support plugin and configure it as mentioned here: https://clojure-lsp.io/clients/ Now whenever I open a project, I get this error message. Any ideas?

👀 1
🐛 2
lsenjov12:09:27

Is there a reason you're doing just the clojure-lsp instead of the #cursive plugin?

lsenjov12:09:24

As for what's going on with the error, is lein in your classpath?

lsenjov12:09:55

It looks like it's trying to run lein and can't find it

Elior Digmi13:09:38

Thanks for the reply! 1. I have cursive plugin already installed. Is there any reason to have both plugins? 2. As for the second question, how can I check it? I'm trying to figure it out on my own but can't seem to find a proper answer.

lsenjov13:09:47

1. Cursive should come with clojure-lsp installed? Or at least be using it under the hood, I'd be very surprised if it didn't. I'd ask in #cursive 2. https://github.com/clojure/java.classpath at a quick google to give you a full list of the classpath contents

lassemaatta13:09:03

I’m almost certain cursive doesn’t use lsp, I think it has it’s own engine for static analysis (disclaimer: it’s been a while since I’ve used cursive).

1
☝️ 1
lsenjov13:09:43

Scratch my number 1 then. Actually @U040FH3EFPV, do you have lein installed on your system?

lsenjov13:09:35

Or did you only install IntelliJ + Cursive + clojure-lsp?

Elior Digmi13:09:14

Yes, I have lein installed, and as for my java.classpath, I don't see lein there. I do remember that when I installed LSP Support plugin, it required Cursive installed.

lassemaatta13:09:44

https://clojure-lsp.io/settings/#classpath-scan some documentation regarding what clojure-lsp does when starting, which should explain why it's trying to run leiningen

❤️ 1
lsenjov13:09:43

Do a dirty and make a shortcut to lein in the project's working directory?

lassemaatta13:09:39

are you sure lein is available in your PATH? the clojure-lsp binary will attempt to run lein classpath [some options] but that error indicates that it can't find the lein command

Elior Digmi14:09:19

Thanks @U0178V2SLAY, I now understand the situation better. As for my PATH, I installed lein via Homebrew. Now, when I run lein in my IntelliJ terminal, it runs fine. That means lein is in my PATH, isn't it?

lassemaatta14:09:27

> I do remember that when I installed LSP Support plugin, it required Cursive installed. That's a bit strange. The LSP support plugin for Intellij IDEA acts as the language-agnostic LSP client (that is, it doesn't know anything about different programming languages or their specifics but knows how IDEA works) while another program (in this case clojure-lsp) acts as the LSP server (it knows about clojure, but not about IDEA) and these two use the LSP protocol to communicate with each other.

lassemaatta14:09:38

you might want to try the normal macos Terminal app to check it, just to rule out IDEA doing something strange with the environment

Elior Digmi14:09:57

Tried that also, runs fine.

lassemaatta14:09:09

you might be able to explicitly configure the classpath scanning options by creating a file .lsp/config.edn within your project (if it doesn't already exits) and add:

{:project-specs [{:project-path "project.clj"
                  :classpath-cmd ["/the/full/absolute/path/to/lein" "with-profile" "+test,+dev" "classpath"]}]}

lassemaatta14:09:51

and replace /the/full/absolute/path/to/lein with the appropriate path to lein

lassemaatta14:09:46

I'm not sure why clojure-lsp is not resolving the path automatically, I assume the process is not inheriting the same PATH as your terminal but I don't know how to resolve this in macos.

lsenjov14:09:55

Dumb question: did you install lein after opening intellij? Or have you restarted your machine recently? I hate asking the "have you tried rebooting" but it might be a fixer here

lassemaatta14:09:43

and if all else fails you can just fallback to using cursive. I think cursive and lsp have a lot of overlap so I imagine you only need one or the other but not both at the same time :man-shrugging:

Elior Digmi14:09:48

@U24QP2D4J Installed lein before opening IntelliJ. Anyways, tried a reboot and it doesn't seem to work. @U0178V2SLAY As for your solution, it doesn't seem to work either. I didn't have the dir nor the file in my project dir, and after creating them it still didn't resolve the issue. I think I'll pass for now and I'll update here if anything will come up. EDIT: @U8SJSCFN3 your solution did work! My IntelliJ doesn't seem to know the my lein location, and only after configuring it correctly in the .lsp/config.edn (which wasn't created automatically), the problem seemed to resolve. Any idea how to make this process work automatically when creating a new project? Maybe something I missed during the installation process? Thank you all for your help!

lassemaatta16:09:33

the problem might have something to do with the LSP plugin for IDEA. There's a couple of issues like https://github.com/gtache/intellij-lsp/issues/147 which look similar to your issue

lassemaatta16:09:01

if you use leiningen for all your projects, you might be able to move that project-specs configuration to the https://clojure-lsp.io/settings/#global so that it applies to all clojure lsp projects

1
Elior Digmi09:09:42

@U0178V2SLAY Worked like a charm. Thanks a lot!

👍 1
ericdallo12:09:44

Yeah, unfortunatelly the LSP plugin for intellij Is way outdated, but I have plans to have a new plugin in the future 🤞

thanks3 1
Gabriel Kovacs21:09:15

Hi! I am going through the https://www.learn-clojurescript.com/section-2/lesson-13-interacting-with-javascript-data/ section. I have reached this exercise where I need to get the grade for the Math course from a student.

(def student #js {"locker" 212
                  "grades" {"Math" "A",
                            "Physics" "B",
                            "English" "A+"}})
I tried (.. student -grades -Math) and I always got nil . After some googling I noticed that by changing the declaration of the student to
(def student #js {"locker" 212
                  "grades" #js {"Math" "A",
                            "Physics" "B",
                            "English" "A+"}})
the initial attempt worked. Did the first declaration of the student contain a syntax error? Would it be possible to retrieve the Math grade from the first declaration of the student?

dpsutton21:09:58

#js is not a recursive tag. Just top level:

cljs.user=> #js {:a 1 :b {:c 3}}
#js {:a 1, :b {:c 3}}
cljs.user=> (type *1)
#object[Object]
cljs.user=> #js {:a 1 :b {:c 3}}
#js {:a 1, :b {:c 3}}
cljs.user=> (type (.-b *1))
cljs.core/PersistentArrayMap

👍 1