Fork me on GitHub
#clojurescript
<
2021-10-13
>
v3ga00:10:09

can someone tell me how to save my ‘architect_id’ field as an integer? https://gist.github.com/v3gal0g/2d7d1174e30e4b16408b259dad903a38

tessocog01:10:55

what do you mean "save"?

v3ga01:10:07

Sorry about that, I want to grab an integer from that field opposed to a string. I’m fairly new to web dev in general so I’m not quite sure what to ask for. that field in my database can only be an integer. So since it’s going through as string it’s not valid. https://github.com/v3gal0g/cybernest-xd/blob/main/src/cljs/cybernest_xd/core.cljs

tessocog01:10:40

is this what you're looking for?:

(cljs.reader/read-string "1")

v3ga01:10:10

No pretty sure it’s not. I’m wanting to capture an integer. I suppose I should handle it on the backend though i’m just curious how someone would go about capturing an integer in a field and sending it as an int via json.

v3ga02:10:54

i’m looking to do something like parseInt I think?

tessocog02:10:49

on jvm:

(java.lang.Integer/parseInt "1")

tessocog02:10:51

on browser: (js/parseInt "1")

tessocog02:10:54

you may find spec useful for this kind of stuff

tessocog02:10:38

really powerful

tessocog03:10:56

also the forms' raw value is always a string

👍 1
v3ga03:10:29

Yeah I'm seeing that now. Yeah I'm going to use spec or malli soon. Just sort of toying around. JS/parseInt is what I want but still not sure, I'm willing to bet there's something im missing here. I suppose this is where ‘coercion’ comes in to play as well on the backend

tessocog03:10:53

i have to clarify my previous statement about form values: that 'is' up there is what i think!

tessocog03:10:34

since the browser may decide to implement ever more "features", and move the threshold of our ignorance while we're sleeping it might be a good idea to be as dumb as possible

👍 1
v3ga03:10:52

I’m going to call it a night. Now what I had working isn’t…and even after checking the diff between my current and what worked it’s the same.

tessocog04:10:06

is the frontend trying to talk to an iota peer?

v3ga04:10:48

yeah its talking to my backend. its all public. still a horrible mess,just hacking around. https://github.com/v3gal0g/cybernest-xd/blob/main/src/cljs/cybernest_xd/core.cljs

tessocog06:10:57

you need to import the following: [json-html "0.4.7"]

tessocog06:10:08

and use it to turn the fields into json right before sending them

tessocog06:10:44

read the docs about shadow-cljs if its not apparent what is happening

v3ga15:10:00

Hmm, ok, i’ll take a look, thanks

v3ga01:10:07

Sorry about that, I want to grab an integer from that field opposed to a string. I’m fairly new to web dev in general so I’m not quite sure what to ask for. that field in my database can only be an integer. So since it’s going through as string it’s not valid. https://github.com/v3gal0g/cybernest-xd/blob/main/src/cljs/cybernest_xd/core.cljs

v3ga15:10:10

^ additional confusion from my issue above. Has anyone experienced ajax posts randomly not working. I was at least getting my text field to go through and hit the database. I made a few changes and things broke. I then rolled back to my commit that did work and restarted all repls and no dice.

dpsutton16:10:45

If i can give you some advice. You seem to be approaching this as if its a black box and just looking at the database. You have several intermediate steps to look at to see where the data is on its journey. You can log to the console what information is in your form state in the browser. The network tab will show you what is going across the wire so you can see what you are sending. You can tap> or log the incoming request, and then tap or log the params passed to your database saving function. And if you can think of what you expect the data to look like in each of these steps you can figure out where it no longer looks like what you expect

👍 1
v3ga16:10:50

Yeah at the moment i’m derefing the field and printing to the JS console. I see it. And even on the backend I see my pedestal route firing off. Its just blowing my mind that it initially saved and even with the same code it’s doing something differently now. I’ve made a mistake somewhere.

dpsutton16:10:23

where in that process does the data not look like what you expect?

v3ga16:10:06

So now what it’s doing is it’s creating a blank row in my database each time I attempt an AJAX post https://imgur.com/gallery/cWbhwsA

dpsutton17:10:27

so i'm not sure how to add more without restating above. Does the network tab show that all of the data you expect is going over? If you change your database saving function to just log and not save the rows, does it end up with all of the data you expect?

v3ga17:10:04

Right, sorry. 200 response but no, no data is going over.

v3ga17:10:35

Ok so sorry to add to the confusion, so I’m using hashp to attempt to print the data from post out in my repl. I’ve commented my line out that would write to the database. Re-evaluated it, saved, etc. It still calls that db transaction and makes another row. I’m going to restart emacs. There’s something funky going on here…

p-himik17:10:42

You're probably holding a reference to insert-iota somewhere. E.g.

(def insert-iota ...)
(def my-do-stuff (prepare do-stuff insert-iota))
In this scenario, after my-do-stuff is created, re-evaluating just insert-iota won't change the already existing reference created by that prepare.

v3ga17:10:35

Hmm, ok… that makes sense. I’m going to take a walk then come back and do some cleaning up and reorganizing my code and I’ll track that down. Is there a pattern or something I can do within cider to flush everything? I assumed just resetting with integrant would clean something like that out.

p-himik18:10:34

Two common approaches - a manual one and an automatic one. The manual one is adding #' in front of all the usages of any var that you think you might want to reload. It's called var-quote, and while I'm struggling to find an article on it, there's some discussion here: https://clojurians-log.clojureverse.org/beginners/2017-03-23 The automatic one is usually called "reloaded workflow" or something like that. It means using clojure.tools.namespace.repl/refresh, usually along with some IoC library, like Integrant, Component, Mount, etc.

👍 1
v3ga18:10:15

Ok yes, I use integrant though I’ll be honest this time I didn’t (reset) this last time… I thought I shut cider down all together but that may have just been my cljs connection. Too much going on getting flustered, but i’ve at least been directed to a few new places to debug…

v3ga19:10:05

Ok a true reset helped. I’m at least getting a 500 error. That makes more sense, before it wasn’t giving me anything meaningful that it was failing.

Apple19:10:37

What's the difference in returning [:div ...] vs wrapping it in an fn like (fn [] [:div ...]) ?

lilactown19:10:06

one is a vector and the other is a function that returns a vector. is there more context to your question?

Apple19:10:21

Reagent. Sorry.

lilactown19:10:37

still not sure. what's the context you're using [:div ...] or (fn [] [:div ...])?

Apple19:10:45

It's hiccup syntax so reagent/react will render the [] or render the result of ((fn ...))

isak19:10:29

You probably mean the return value of (defn my-component [] ...) when rendered like [my-component ...] elsewhere, right?

Apple19:10:34

I feel as long as at least one ratom is used then they are the same.

isak19:10:12

@zengxh the function wrapped one allows you to close over a ratom (or similar) that you create in the outer scope, so that it doesn't get created every render (making it useless for controlling renders)

✔️ 1
pesterhazy19:10:56

You end up with a different tree of react components

Apple19:10:04

I test this

(def seconds-elapsed (r/atom 10))
(js/setTimeout #(swap! seconds-elapsed inc) 1000)

(defn test1 []
  (let []     ;; setup, and local state
    [:div "Seconds Elapsed: " @seconds-elapsed]))
and this
(def seconds-elapsed (r/atom 10))
(js/setTimeout #(swap! seconds-elapsed inc) 1000)

(defn test1 []
  (let []     ;; setup, and local state
    (fn []        ;; inner, render function is returned
      [:div "Seconds Elapsed: " @seconds-elapsed])))
it shows 10 then 11 then stays 11.

Apple19:10:50

always 10

(defn test1 []
  (let [seconds-elapsed (r/atom 10)]     ;; setup, and local state
    (js/setTimeout #(swap! seconds-elapsed inc) 1000)
    [:div "Seconds Elapsed: " @seconds-elapsed]))

metasoarous19:10:03

It's not surprising that this always stays ten, since once the timeout triggers, the seconds-elapsed atom updates, triggering a rerender of the component, which in turn ends up defining a new seconds-elapsed atom set back to 10, with a new timeout, etc.

❤️ 1
Apple19:10:24

obviously the doc example works

(defn test1 []
  (let [seconds-elapsed (r/atom 10)]     ;; setup, and local state
    (fn []        ;; inner, render function is returned
      (js/setTimeout #(swap! seconds-elapsed inc) 1000)
      [:div "Seconds Elapsed: " @seconds-elapsed])))

Apple19:10:25

I guess i understand the last two which address my original question. Returning a [] is a one time effort while returning a (fn ...) causes reagent to tract the ratom inside

p-himik19:10:41

That's the difference between form-1 and form-2 components. It's well documented.

metasoarous19:10:03

It's not surprising that this always stays ten, since once the timeout triggers, the seconds-elapsed atom updates, triggering a rerender of the component, which in turn ends up defining a new seconds-elapsed atom set back to 10, with a new timeout, etc.

❤️ 1
metasoarous19:10:31

@zengxh Yes; So when you use the 2-form, the outer function only gets called once, meaning there's only ever one atom being created

Apple19:10:39

what's the reason for the first two 10->11 usage?

p-himik19:10:44

Unclear what you mean exactly. But the state is outside of the components, so re-rendering the components doesn't alter it. There's also #reagent - new questions on it should probably be asked there.

✔️ 1
metasoarous19:10:45

You mean where the ratom is defined in a def form, outside of the component definition?

metasoarous19:10:02

As @p-himik points out, there the state is outside the components, so re-rendering the components doesn't reset the atom state back to ten.

metasoarous19:10:55

In those cases, with the ratom defined on the outside of the components, the two approaches (1-form and 2-form) are equivalent, because there's no state that's local to the component. The 2-form is only really useful when you want a component to have some local state that it's in control of.

Apple20:10:57

I check the value of @seconds-elapsed and it's indeed 11 not changed. I thought the setTimeout would bump it up regardless of the rendering...

Apple20:10:46

(def x
  (let [tt (atom 10)]
    (js/setTimeout #(swap! tt inc) 1000)
    tt))
@x is always 11

Apple20:10:19

silly me it's setTimeout not setInterval . 🤕

metasoarous22:10:55

Oh; LOL. Now I see why you were confused (and what you were expecting).