Fork me on GitHub
#clojurescript
<
2018-08-30
>
idiomancy00:08:05

hey, somebody answered this question for somebody else last week and I forgot to save it, because it was interesting to me. I want to create an aliased namespace without making a file. its 2 steps. you do something to create the ns and then (alias ns-sym :as 'alias)

idiomancy12:08:42

outstanding, thanks! it even comes with ideas on how to do it in cljs!!

idiomancy00:08:13

anybody know what I'm talking about?

thheller08:08:11

@idiomancy that only works in CLJ though. There is no support for this in CLJS besides creating an actual empty ns.

idiomancy12:08:20

oh, good heads up 😅

eval202012:08:08

how can I do a conditional :require based on whether I’m targetting node or browser? currently I have:

;; src/foo/core.cljs
(ns foo.core
  (:require websocket))
I guess what I want is a custom reader conditional?, e.g. #?(:nodejs ...)

bhauman12:08:06

@eval2020 there are a couple of ways to do this

bhauman12:08:52

one is by using different builds with different source directories

bhauman12:08:20

you can also add preloads for different builds

bhauman12:08:03

you can create a macro that looks at your compile options and conditionally emits code based on your target

bhauman12:08:36

you don’t have to explicitly require something to access it if its in your preloads

bhauman12:08:03

you can also do code splitting and dynamically load a module

bhauman12:08:57

but an important thing to remember is that advanced compilation DCE can eliminate code at compile time so often you don’t have to do this stuff at all

👌 4
eval202012:08:40

@bhauman thanks!, plenty of options 🙂 . I’ll try preloads for now

bhauman12:08:43

there is also closure-defines, in conjunction with a conditional will almost guarantee dead code elimination

bhauman12:08:44

hold the phone is that @william

💯 4
williamblasko12:08:12

Doing some cljs noodling on relaxed vacation at the in-laws. @eggsyntax suggested I join up here.

4
bhauman12:08:57

well that sounds good all around, where are you?

williamblasko12:08:39

Shelter Island, NY.

bhauman12:08:45

@william Very cool well let me know if I can help. here’s a tutorial https://figwheel.org/tutorial

idiomancy12:08:54

Good morning! So, what's the cljs answer to intern? I need to monkey patch a library im using which, in clojure I did by saying (intern 'external.library.core 'old-function-sym my-function-sym)

bhauman12:08:23

@idiomancy well that doesn’t exist

bhauman12:08:49

is this for prod or testing?

idiomancy12:08:58

ehhhh, I mean

idiomancy12:08:17

you're gonna tell me to fork it?

bhauman12:08:28

no I’m just wondering the context

bhauman12:08:41

because you can patch the underlying js

bhauman12:08:12

but that is not gonna fly so well

idiomancy12:08:23

ahh, interesting. Well, I assume it will eventually get used in prod, I'm making a drop in bit of code to apply globally whenever I use garden

bhauman12:08:26

when it comes to advanced compilation

idiomancy12:08:24

garden doesn't support @supports feature queries, so I extended it

idiomancy12:08:56

but I have to replace a compiler function that dispatches a value

idiomancy12:08:14

(garden compiler, that is)

bhauman12:08:46

yeah a patch to garden sounds like a much better approach

bhauman12:08:06

as it would benefit lots of folks

idiomancy13:08:33

I've spoken to noprompt. He has a whole 2.0.0 he wants to roll out that almost has all of the pieces assembled. He hasn't been working on it lately, though - no frontend contracts. So he's unlikely to go for a PR into the version that will become obsolete whenever he decides to keep working on it

idiomancy13:08:11

so, that's where I'm at ¯\(ツ)

bhauman13:08:07

I don’t see any reason he shouldn’t accept the PR, but you are probably better off with the forked version than a patch

bhauman13:08:34

while you are waiting

idiomancy13:08:07

Yeah, I see what you're saying. what do you think @U06MDAPTP?

idiomancy13:08:05

Joel, you're the man, we can handle it however you want. You keep doing you and I'll help however I can

idiomancy13:08:04

thanks, btw @bhauman! sometimes the advice you need is just "yes, you should do it the right way" 😆

grav14:08:43

On the other hand, by patching the underlying js, you’ll have short-term gratification and long-term job security 😉

👿 8
noprompt17:08:20

@idiomancy i’m fine to patch the current branch. i’ll review your patch as soon as i am able. current status: underwater. 🙂

idiomancy17:08:20

Word. I totally get it. Cheers!

noprompt17:08:49

i’ve got a tab open for the PR so i don’t forget to get to it.

dnolen14:08:06

@idiomancy monkey patching a lib is pretty straightforward though - set! works for this even under advanced compilation

idiomancy14:08:35

oh, the temptation

bhauman18:08:48

oh yeah, I forgot

idiomancy21:08:06

well forgotten! it led to a patch to garden 😄

idiomancy15:08:53

so on a related note, what's the best way to depend on a github project, like maybe a fork to a popular cljs css repository

john17:08:58

@idiomancy With the new tools.deps (deps.edn) you can depend on the commit hash of a project on github directly.

Ramzi18:08:15

I am making an ajax call and successfully getting {:data "Hello World"}{:data "Hello World"}{:data "Hello World"}{:data "Hello World"}{:data "Hello World"}{:data "Hello World"} back from the database. Problem is I can only see it in my network tab. I can't seem to alert it or write it to a div. Here's my attempt: (defn ajax-input [id] [:input {:id id :on-change #(js/alert (.-value (.send goog.net.XhrIo "/database"))) } ] )

defn18:08:45

@idiomancy here's an example from https://clojure.org/reference/deps_and_cli

{:deps
 {org.clojure/tools.reader {:mvn/version "1.1.1"}
  github-sally/awesome {:git/url "", :sha "123abcd549214b5cba04002b6875bdf59f9d88b6"}
  ;; ... add more here
 }}

bhauman18:08:58

@its.ramzi ajax is async it doesn’t return the result

bhauman18:08:21

you have to listen for it

bhauman18:08:50

one way or another I believe send returns a promise

Ramzi18:08:39

how do i get the result from what send returns

Ramzi18:08:00

Can you help me translate this to clojure: goog.net.XhrIo.send(dataUrl, function(e) { var xhr = e.target; var obj = xhr.getResponseJson(); log('Received Json data object with title property of "' + obj['title'] + '"'); alert(obj['content']); });

Ramzi18:08:04

The current way i'm doing it is: (.send goog.net.XhrIo "/database")

Ramzi18:08:21

so I dont get those dataUrl and e parameters there

bhauman18:08:01

@its.ramzi (.send goog.net.XhrIo "/database" (fn [event] ;; get data from event here ))

Ramzi18:08:13

let me try that

Ramzi19:08:01

:on-change #(.log js/console (.send goog.net.XhrIo "/database" (fn [event] (.getReponseJson(.target event)))))

Ramzi19:08:21

i didnt see anything in my console log

Ramzi19:08:03

event.target is not a function

lilactown19:08:58

you’re calling event.target like a function

john19:08:04

Yeah, you want (.-target event)

Ramzi19:08:47

.target.getReponseJson is not a function

john19:08:55

that returns the value of the thing at the property target, rather than calling a function at that property

Ramzi19:08:47

Great! Getting closer! json.js:148 Uncaught Error: Invalid JSON string: {:data "Hello World"}{:data "Hello World"}{:data "Hello World"}{:data "Hello World"}{:data "Hello World"}{:data "Hello World"}{:data "Hello World"}{:data "Hello World"}{:data "Hello World"}

parrot 8
Ramzi19:08:55

So I wrapped my {}s with a []. Now it is coming in as [LazySeq] and still causing the invalid json error

Ramzi19:08:16

json.js:148 Uncaught Error: Invalid JSON string: [clojure.lang.LazySeq@f2575201]

Ramzi19:08:00

oh, because there are no commas?

thheller19:08:13

@its.ramzi don't use .getResponseJson use .getResponseText instead

thheller19:08:50

then use (:require [cljs.creader :as reader]) and (reader/read-string the-result) to convert the text to cljs maps

thheller19:08:19

that is on the client. on the server make it return what it returned previously

Ramzi19:08:45

it shouldnt matter if i wrap it in [] or not

Ramzi19:08:16

using .getResponseText gives me: Uncaught TypeError: Cannot read property 'value' of null

Ramzi19:08:59

Sweet! I got the db data to alert!

Ramzi19:08:04

Now to just write it to a DOM element

Ramzi19:08:17

I think the "changeme" div isn't loaded yet. (defn change-dom [content] (-> js/document (.getElementById "changeme") (.-innerHTML)(set! (-> js/document (.getElementById n)(.-value)(str content)) )) )

john19:08:00

typo there

Ramzi19:08:12

what is n

john19:08:41

ah sorry your code style there threw me off

john19:08:34

Fix up your indentations so we know what you meant to convey

dpsutton19:08:39

and use code formatting with three backticks

three back ticks

john19:08:03

Your code, properly indented, looks more like this:

(defn change-dom [content]
    (-> js/document
        (.getElementById "changeme")
        (.-innerHTML)
        (set!
         (-> js/document
             (.getElementById n)
             (.-value)
             (str content)))))

john19:08:56

I'm not sure what you were trying to accomplish there. But you can probably just replace that last (set! ... with (set! content)

Ramzi19:08:11

I am trying to write the db results into a div

john19:08:41

Yeah, I'm not sure what n is supposed to mean there

Ramzi19:08:04

im surprised my compiler rwasnt complaining

Ramzi19:08:13

i tried replacing it with "changeme" but i still get the same null error

Ramzi19:08:20

alerting content works fine

john19:08:08

sounds like you're almost there

Ramzi19:08:30

i tried intoing into a div, and into body, with no luck

Ramzi19:08:41

why is it finding null for div "changeme" when it's already on the page?

Ramzi19:08:08

oh snap, it'

Ramzi19:08:16

s not on the page. id = [Object object]

john19:08:04

yeah, I think your above function may have accidentally did that. Try first making a basic function that can add text to a div

john19:08:14

Just one div and one piece of text

Ramzi19:08:45

Sweet! I got it!

Ramzi19:08:51

db info printed to a div!

Ramzi19:08:00

i should go home early

john19:08:14

Nice! refer to this too when translating from js code: https://kanaka.github.io/clojurescript/web/synonym.html

john20:08:02

If one wants to release a ClojureScript lib on NPM and make it maximally usable by the greatest number of JS devs, what are the JS ecosystem things a CLJS dev should take into consideration?

nha09:08:14

Same thing here - I wish it was a better supported use-case (in my case I may prototype in cljs, but will probably have to rewrite at some point 😑)

dnolen20:08:39

that’s just not a very popular thing to do for the reason that nobody will want to use your thing client side unless they’re going to run Google Closure on it

dnolen20:08:42

which they probably won’t

john20:08:05

Yeah, I wasn't able to find many libs out there produced with closure. I understand React is ran through it (at FB), but I guess that's just for prod. But if the output is set to :none or :simple, are other minifier/packer tools not able to consume that output?

dnolen20:08:11

what I mean rather is we generate lot of code and it’s very verbose

dnolen20:08:19

but that’s because we assume Closure will run on it

dnolen20:08:53

since what you’d be shipping on npm would have to be code compiled with :none nobody will be able to handle that

dnolen20:08:15

independently compiling stuff also doesn’t work

dnolen20:08:35

data structures will be considered different

john20:08:24

Ah, so datascript is just delivering a minified artifact via npm. And your mori is running lein from the npm build command.

john20:08:54

Minified artifacts should be good enough for my target audience, as this is more of a tool, used with code, than a lib.

john20:08:02

So, wrt distributing minified CLJS to the JS world, are there any other gotchas or assumptions to be aware of about JS consumers?

john20:08:05

I got a good idea of how to manage exported functions

dnolen20:08:49

right you just need to understand that datascript and mori etc. are not compatible

dnolen20:08:53

they can’t be used together

dnolen20:08:29

if you’re fine with all of these limitations then, sure, datascript & mori are how it’s done

john20:08:55

This may be too ambitious, but I'd like to code split my tool into a bunch of different, optional artifacts. If certain modules are pulled, they may pull in other modules (off the CDN). I'm thinking this will all continue to just work, even when being called from the JS side.

dnolen20:08:04

well just not possible in a way that’s practical for end users

dnolen20:08:46

(JavaScript end users)

john20:08:20

Why so? I wouldn't be passing control of the dependency stuff over to the JS users.

dnolen20:08:39

you can’t split code into independent modules like that

dnolen20:08:49

the code splitting we have is only about browser clients

john21:08:10

I'm targeting browser. I just said npm because that seems like the JS distribution channel most clients will be familiar with.

john21:08:40

ooh, but yea...

john21:08:25

Could it be possible to make multiple code-splitted-modules available on npm, and once their downloaded and up in a user's assets folder, they'd be in the right place? Similar to how it'd work if they were pulling the root artifact off of a CDN, which also contains the rest of the splits?

john21:08:15

I may be getting too esoteric with the use cases. I'm just wondering what I can offer and I'm still learning the JS ecosystem. It seems to change faster than you can learn it though 🙂

exit222:08:17

I’m getting a WARNING - unreachable code when trying to compile my project after adding a node module via npm-deps. Has anyone seen this before?

idiomancy22:08:04

thanks @john, @iam! works great!

idiomancy22:08:01

Hey, does anybody know of anyone know of any good ways to organize components with configurable colors? How do I describe this problem lol.

idiomancy22:08:26

I'm trying to set up a personal library of components which I can include across projects by putting a bunch of dynamic variables at the top of the namespace. so like

(def ^:dynamic a-color "#ffffff")

(defn a-component [& args]
    [:div.box {:style {:background-color a-color}}])
that way I could have those vars dynamically replaced with different configuration sets. right? make sense? Well here's the thing lol, what do I name the color constants? because like, while I'm programming, I don't want to see, like, *color-001* as a constant, that's not descriptive at all... but I don't want to say like *green* if I'm gonna remap it to another color later 😆

idiomancy22:08:29

I feel like I lack the human language to describe color in terms of its function. I've got numbers and colors, and neither one seems appropriate lol

dpsutton22:08:48

should they be named conceptually? "accent" "main" "background" "branding" ...

dpsutton22:08:31

or think of palettes. take 5 colors and just use numbers

idiomancy22:08:54

yeah, I guess they should, I guess I should be putting this question to designer friends, because I like, don't know enough conceptual language

idiomancy22:08:38

when you said "accent" there i was like "oh man thats great!" I'm at kindergarten level for design vocab 😅

idiomancy22:08:21

ooh, okay, I think I'm getting closer... so, there are a couple ways to choose color schemes apparently. you have have a triadic color scheme or a complementary scheme or a split complementary, etc. Maybe if I make a couple of those pallets, and then maybe have a function that chooses colors depending on what's defined? Man I am over engineering the living hell out of this

exit223:08:03

Does anyone know if there is a way to tell the closure compiler to ignore certain files from project.clj? (i.e. node_modules)

dnolen23:08:13

:npm-deps false disables reading from node_modules

exit212:08:02

I have node modules that I’m installing via :npm-deps, which is listed under the :compiler map. Unless I this goes elsewhere in the config and flags to not run the closure compiler on build?