This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-06-29
Channels
- # admin-announcements (4)
- # arachne (19)
- # aws-lambda (3)
- # beginners (10)
- # boot (166)
- # capetown (32)
- # carry (160)
- # cider (5)
- # cljs-dev (5)
- # cljs-edn (19)
- # cljsrn (1)
- # clojure (100)
- # clojure-belgium (2)
- # clojure-dev (8)
- # clojure-greece (13)
- # clojure-new-zealand (12)
- # clojure-poland (1)
- # clojure-russia (93)
- # clojure-sanfrancisco (2)
- # clojure-spec (133)
- # clojure-uk (52)
- # clojurescript (129)
- # cursive (32)
- # datomic (13)
- # defnpodcast (5)
- # devcards (6)
- # dirac (4)
- # emacs (12)
- # euroclojure (5)
- # events (2)
- # hoplon (19)
- # immutant (45)
- # keechma (17)
- # lein-figwheel (27)
- # off-topic (9)
- # om (30)
- # onyx (17)
- # other-languages (3)
- # planck (2)
- # proton (11)
- # re-frame (7)
- # reagent (4)
- # ring (8)
- # sim-testing (2)
- # spacemacs (4)
- # testing (2)
- # untangled (162)
- # utah-clojurians (1)
- # yada (80)
Does it have to be that dynamic? If you know the set of functions that can be called this way, then just (def funcs {"func1" func1, "func2" func2})
etc, and look it up when it's time to call.
yeah, it doesn't have to be arbitrarily dynamic, though reverse lookup is the trick
basically i want to call a function that calls the intended function, and as a side effect caches the key that i can use to look it up for next time
is there, like, a bidirectional map, maybe?
ok, thanks for the map idea š i usually just reach straight for the power tools in clj, but sometimes simpler is better
Unrelated: am I reinventing a wheel here or does bidi provide a way for parsing query params?
(defn my-match-route [rs s]
(let [url (cemerick.url/url s)]
(when-let [r (bidi.bidi/match-route rs (:path url))]
(assoc r :query-params (:query url)))))
@dnolen: One thing Iāve noticed with this - for some reason, arglists and params seem to be gensymāed - is that expected or am I doing something wrong?
(get-in result [:cljs.analyzer/namespaces 'om.dom :defs 'br :meta])
=>
{:arglists (quote ([opts__9332__auto__ & children__9333__auto__])),
:top-fn {:variadic true,
:max-fixed-arity 1,
:method-params [(opts__9332__auto__ children__9333__auto__)],
:arglists ([opts__9332__auto__ & children__9333__auto__]),
:arglists-meta (nil)},
:file nil}
Actually, this isnāt all of them - it might just be a problem with the way that om.dom is generated.
Iām running cljs in electronjs on Windows 10, and am hitting an interesting and hard problem regarding cljs.core.load_file being passed forward slashes instead of backslashes. Anyone run into this before? Iām requiring a cljsjs namespace. The forward slashes end up as tabs, as in āapp\target\moment.inc.jsā -> āapp argetmoment.inc.js"
Is there a way to ensure the slashes get escaped?
my fuzzy answer: experiment with double slashes. because Unix/Java world and Windows world generally have opposite leaning slashes, so anything that bridges those two worlds ends up with counter-intuitive multiple level of slash escaping. // \/ \\ etc etc. may be faster to try several permutations quickly, see which passes through
ns
and the compiler construct the path, so I think either I need to change some sort of compiler option or thereās some kind of environmental variable
that I might need to use
Or, itās a weird bug?
@wildermuthn: you might need 3 or more levels of escapes, potentially. depends on how many parsing/encoding phases it must survive through before hitting the real file system query
@wildermuthn: longer/slower answer is stop using Windows/Microsoft and get away from heavily indirect/abstracted toolsets (Clojurescript/Clojure/Java/Unixy/Windows?) which are more prone to this kind of pain. but that's a longer term solution, I know, sorry. š
Iāll try giving up tomorrow. š
@wildermuthn another fuzzy partial answer, almost every smart language/stdlib has the notion of FILEPATH_SEPARATOR, which lets you build filepath strings using it, and it provides a signal that can more robustly pass-through down to the bottommost layers of the call graph, and more likely to safely get translated into the host OS expected filepath separator. if Clojurescript/Clojure has such a thing, use that, rather than a hard-coded "\" inside your strings. Does this make sense? sorry for the indirect answer. am a Clojure newb, though have dealt with many languages over the years, this is a recurring problem.
Thanks @groglogic, I think I only needed to include the js library manually rather than letting cljsjs define foreign paths that use backslashes.
There is probably a better way to do this, but I ended up calling (cljs.core/load-file āapp\\resources\\public\\js\\lib\\moment.min.jsā)
and that seems to work! š
Running nodejs on electron, trying to get around path problems on Window with cljsj/moment ^
@danburton: ah wait you actually used that in your example, right there. d'uh!
Hey Folks š Wondering if anyone may be able to help me out? I've been learning ClojureScript & Om for a couple of days now. I also shared this post in the Om channel. I am having a problem in regards to the following code snippet below:
;; Build the todo-input area to enter a todo task and then when
;; a user hits the return key, add the todo to the list area.
(defn todo-input [todos owner]
(om/component
(html
[:input ;; Type input -> text.
{:type "text"
:placeholder "What needs doing?"
:on-key-up (fn [event] ;; Trigger an event handler.
(let [input (.-target event)]
(when (= 13 (.-keyCode event)) ;; When user hits ENTER.
(om/transact! todos ;; Evlautation closure.
(partial add-todo (.-value input))) ;; Take the value of input.
(set! (.-value input) ""))))} ;; After add-todo method has been executed -> reset input.
])))
;; Build the add-todo button to capture the input value and add
;; task to the list of todo items. No return key functionality required.
(defn todo-add-btn [todos owner]
(om/component
(html
[:button {:class "add-btn" ;; Button type with class add-btn.
:on-click (fn [event] ;; Trigger an event and function.
(let [input (.-target event)] ;; Event handler.
(om/transact! todos ;; Begin evaluation closure.
(partial add-todo (.-value input))) ;; Take the value of input.
(set! (.-value input) "")))} "Add task" ;; After adding todo item -> reset input.
])))
Essentially, I am unable to capture the value of input
when the todo-add-btn
submits on-click
? My assumptions are that the input
is a global variable that also needs to be in the scope of the function todo-add-btn
? How would I go about doing this or have I got it wrong?@kauko: Yeah, it seems as though the method to add any todo task entered into the input field works when hitting the todo-add-btn
ā¦ However, nothing is returned or captured, just a blank task. From discussions elsewhere, it looks like the on-key-up
(fn [event]ā¦
and -target event
in the todo-input
method is binded to the input
html
element itself, capturing the value. This makes sense as to why it works.
In the todo-add-btn
method, the on-click
is trying to do the same but as the element is a button
it attaches itself to the button, hence capturing nothing. It may be best to perhaps have some sort of state in between, that can be used in both the methods to capture the input value?
So something like
In on-key-up
, we have a state called editing-text
or (om/transact! :editing-text ā¦.
.
Then in on-click
, we take the data stored in editing-text
as (om/transact! todos ā¦ editing-text ā¦)
passing it through?
Would a strategy like this be achievable?
@dnolen: What is the purpose of the IAtom
protocol? What kinds of things should satisfy it? If I have something that can be watched and dereferenced, but not reset or swapped (so it's read-only), should it be an IAtom
? Should IAtoms
be writable?
@kauko: there's IDeref
and IWatchable
@anmonteiro: there's also IReset
and ISwap
, I'd like to know if I should use a combination of these for checking whether an atom is writable, or just use IAtom
@kauko: I can't be sure but I'd say that IAtom
should be just for atoms (or your own atom impl). If you're implementing something that's not writable just go with IWatchable
and IDeref
IMO
so if I have my own atom implementation that is writable and readable, that should satisfy IAtom?
Yes if you want transparent support for other libs that might rely on that check
@kauko: e.g. https://github.com/reagent-project/reagent/blob/master/src/reagent/ratom.cljs#L121
Checking for IReset and ISwap is more explicit, but I feel IAtom is the one that should be used
it's just entirely possible that some "custom" atom implementations forget to implement IAtom, but I guess that'd be on them
anyone know if the api was broken with figwheel-sidecar recently? was using figwheel-system
Hello, I'd like to get familiar with om.next, so I'm working through the Quick Start on the github page. I'm unable to get the first 'Hello world' example up and running. Here's an exerpt from the error message. Is anyone familar with this error?
Compiling target/figwheel_temp/dev/figwheel/connect.cljs
{:tag :cljs/analysis-error}
ANALYSIS ERROR: No such namespace: om-tutorial.core, could not locate om_tutorial/core.cljs, om_tutorial/core.cljc, or Closure namespace "om-tutorial.core" on file null, line null, column null
Exception in thread "main" clojure.lang.ExceptionInfo: Error in component :figwheel-system in system com.stuartsierra.component.SystemMap calling #'com.stuartsierra.component/start {:reason :com.stuartsierra.component/component-function-threw-exception, :function #'com.stuartsierra.component/start, :system-key :figwheel-system, :component #figwheel_sidecar.system.FigwheelSystem{:system #object[clojure.lang.Atom 0x22e9f4f3 {:status :ready, :val #<SystemMap>}]}, :system #<SystemMap>}, compiling:(/home/dfornika/Code/om-tutorial/script/figwheel.clj:4:1)
at clojure.lang.Compiler.load(Compiler.java:7239)
@bhauman Thanks. I've got the project set up just as suggested in the Quick Start. My figwheel script is:
(require '[figwheel-sidecar.repl :as r]
'[figwheel-sidecar.repl-api :as ra])
(ra/start-figwheel!
{:figwheel-options {}
:build-ids ["dev"]
:all-builds
[{:id "dev"
:figwheel true
:source-paths ["src"]
:compiler {:main 'om-tutorial.core
:asset-path "js"
:output-to "resources/public/js/main.js"
:output-dir "resources/public/js"
:verbose true}}]})
(ra/cljs-repl)
so you have made it through the checkpoint and have a om_tutorial directory and that directory name has underscores__
@dfornika: thereās an #C06DT2YSY specific channel btw, lots of knowledgeable people there
@wildermuthn: weāve spent some time solving Windows issues but itās possible we missed something
Obviously I have to just trust that people use it correctly, but what is "correct use" in this case?
If I get an IAtom
, does it mean that the thing can be deref'd, watched, swapped, and reset?
the point of the protocol is to say something satisfies all the the things that the provided Atom
type implements
thereās no enforcement here or anything - but important to do everything otherwise nasty surprises for someone who tries to drop in your Atom
replacement
Hey, so Iām reading some docs and in them thereās "The HTTP response will return a Location
header pointing on the uploaded image.ā
So how would I call a function like getResponseHeader(key)
or getResponseHeader(āLocationā)
I have nothing past (.getResponseHeader ...)
@urbanslug: could you give more context? It could be (js/getResponseHeader key)
or (js/getResponseHeader āLocation")
@dnolen: Thanks for the tip on #C06DT2YSY, I'm sure I'll be spending some time there soon.
@urbanslug: (.getResponseHeader response "Location")
where response
is the object that has the getResponseHeader
method.
ok, i have a very basic (probably) question
basic in terms of understanding level, at least
i have some JS code that i'd like to translate into cljs, or, failing that, some way to just insert the code raw into my main js file
it's here: https://github.com/screepers/screeps-stats , under "Enhanced Stats Collection"
var ScreepsStats = require('screepsstats')
global.Stats = new ScreepsStats()
module.exports.loop = function () {
// Do code stuff!
// Run Stats Last.
Stats.runBuiltinStats()
}
i already have the module.exports.loop
bit working (from previous work), but my code to do those first two lines does not appear to be working the way it's supposed to - I don't actually get the prototype created properly
looking at the generated source, it seems to be equivalent, but it's not exact
i did this:
(set! js/ScreepsStats (js/require "screepsstats"))
(goog.object.set js/global "Stats" (js/ScreepsStats.))
and ((goog.object.get (goog.object.get js/global "Stats") "runBuiltinStats"))
in my loop
(I have an externs file, but this seemed more low-level and thus less prone to error)
but when I call runBuiltinStats
, it doesn't actually have the prototype for ScreepsStats
so the first method call on it fails
the generated code has ScreepsStats = require(...
, not var ScreepsStats
, so I suspect that's what is going wrong. so my question is: how can I get the compiler to generate that var
?
blerk- somehow the āenable sourcemapsā checkbox in devtools settings got unchecked š” - iāll delete the waffle above
probably the first thing i should have checked š
hahah
standard
@anisoptera: is this for Node.js?
@dnolen: no, but I think the semantics are the same
it's for a game about AI programming
@anisoptera: Iām asking because it matters mostly whether you actually need advanced optimizations
I do need optimizations, it makes my dealings with the game API much smoother if it comes out in one big file, and I think I have a somewhat restrictive limit on how much code I can upload
(it sure does make my life a lot harder when debugging, though. no source maps = sad panda)
right
it's not written for node.js, it's written for this game's framework
but i think the same principles apply
i'm uploading the library .js directly
not trying to optimize that š
it's not for the browser, though
like i can see in the code that js/require
is generating the proper call
right, because you just import it via some other method, i saw the various ways to accomplish this in non-play environments
require
isn't a JS feature, right? it's provided by whatever framework you're using
(I know very little about JS itself)
so in this case require
is doing something specific to the game's framework
Iām trying to compile/evaluate some cljs in the browser and getting back the following error: "No *load-fn* setā
Looking around on the web, this appears to be how cljs knows how to load libraries from a :require directive. Am I interpreting that correctly?
@mattyulrich: yes you need to hook up a load-fn
inside the cljs.js/eval-str
method. Depending on what you're trying to do I'd suggest also to have a look at https://github.com/Lambda-X/replumb
I assoc :load-fn!
here and then pass the option map as 4th param in eval-str
https://github.com/Lambda-X/replumb/blob/master/src/cljs/replumb/repl.cljs#L591