Fork me on GitHub
#untangled
<
2017-02-21
>
tony.kay03:02:34

The develop branch of untangled-ui was just updated. I revamped the server delta a bit and wrote a quick doc guide page for it. I'd appreciate anyone looking over the docs and seeing what they think (@baris or @torkan ?) https://github.com/untangled-web/untangled-ui/blob/develop/src/guide/untangled/ui/Forms__03_Server_Integration.cljs

cjmurphy04:02:21

Does anyone else have the problem that IDEA/Cursive wants you to generate stubs, yet that fails? I've taken the css cookbook recipe into its own project and can't generate the stubs. The underlying error message is a Figwheel Configuration Error that the required key :cljsbuild is missing. My problem is that it is there and I can see it.

grant14:02:31

@cjmurphy I have seen the problem before. In my case, it was a dependency problem. But either way, if you have a lein error, Cursive is not going to be happy when it tries to generate stubs. If you can't figure out what's wrong, post your config and someone can probably help you find the issue.

tony.kay17:02:03

@cjmurphy I know exactly what that is

tony.kay17:02:23

I assume you're using an older example or template for Untangled.

tony.kay17:02:32

In user.clj there is a start-figwheel function

tony.kay17:02:24

At the top level there is a def of figwheel config that reads the figwheel config. That is what breaks it

tony.kay17:02:51

please let me know where you got that breakage from, so I can fix it if it is still in one of our repos

tony.kay17:02:57

Here is the approximate fix:

tony.kay17:02:09

(usiung figwheel sidecar 0.5.9):

tony.kay17:02:21

(ns clj.user
  (:require
    [clojure.set :as set]
    [clojure.tools.namespace.repl :refer [refresh]]
    [figwheel-sidecar.system :as fig]
    [com.stuartsierra.component :as component]))

;;FIGWHEEL
(def figwheel (atom nil))

(defn start-figwheel
  "Start Figwheel on the given builds, or defaults to build-ids in `figwheel-config`."
  ([]
   (let [props (System/getProperties)
         figwheel-config (fig/fetch-config)
         all-builds (->> figwheel-config :data :all-builds (mapv :id))]
     (start-figwheel (keys (select-keys props all-builds)))))
  ([build-ids]
   (let [figwheel-config (fig/fetch-config)
         default-build-ids (-> figwheel-config :data :build-ids)
         build-ids (if (empty? build-ids) default-build-ids build-ids)
         preferred-config (assoc-in figwheel-config [:data :build-ids] build-ids)]
     (reset! figwheel (component/system-map
                        :figwheel-system (fig/figwheel-system preferred-config)
                        :css-watcher (fig/css-watcher {:watch-paths ["resources/public/css"]})))
     (println "STARTING FIGWHEEL ON BUILDS: " build-ids)
     (swap! figwheel component/start)
     (fig/cljs-repl (:figwheel-system @figwheel)))))

tony.kay17:02:44

just make it so figwheel doesn't get called during a top-level eval of user

cjmurphy19:02:18

@tony.kay: Yes that fixed the problem. It was in the Cookbook, the example for the css (obviously possibly the others too). The user.clj is old code: https://github.com/untangled-web/untangled-cookbook/blob/master/recipes/css/dev/server/user.clj. Also the css example project.clj uses "0.5.5" of figwheel-sidecar, not "0.5.9".

tony.kay20:02:25

ok. I'll open an issue. Not sure when I'll personally get to it

tony.kay20:02:09

If you have a fork and care to send a PR, that'd be nice 😉

cjmurphy20:02:51

Yes I'll test them all fix if I can, certainly this (css) one anyway. Right now trying to start a Figwheel REPL has got me stumped: "Error: Could not find or load main class script.figwheel.clj". The thing is I've defined the local REPL in IDEA and the working directory and JVM args are correct, so script/figwheel.clj should be being found.

tony.kay20:02:13

script/figwheel.clj

tony.kay20:02:17

in your settings for the run config

tony.kay20:02:35

oh, that is not a main class

tony.kay20:02:43

it is a parameter to REPL startup

tony.kay20:02:57

you have it in the wrong field or perhaps the wrong kind of run config

baris20:02:40

Hey @tony.kay the new documentation on the forms support is great. I think the basics, server-integration and full-stack-demo devcards are a great starting point for everyone who wants to use the forms support. Is the devcard "05-field-interactions" WIP? It's confusing me.

tony.kay20:02:58

it is all WIP 🙂

tony.kay20:02:02

as in right now

tony.kay20:02:19

I'm working on making validation a little more clear...adding a would-be-valid? function

tony.kay20:02:46

I'll push an update in a few hours

baris20:02:54

So I got some other minor things that I noticed today.

tony.kay20:02:06

great. let's fix 'em

baris20:02:16

You changed the source-paths in the project.clj and this configuration doesn't work for me when I start the "guided-demos" with the following command.

baris20:02:26

JVM_OPTS="-Dguide -Dvisuals -Dcss-guide" lein run -m clojure.main script/figwheel.clj

baris20:02:37

I get some compile errors that some files could't be find and loaded. Anyway that's not a big deal at the moment.

tony.kay20:02:13

could be I already fixed that...my builds are all working, but I have not pushed today

baris20:02:31

I also observed a strange behavior with the new forms support on the server side.

tony.kay20:02:50

that would be more interesting 🙂

baris20:02:00

In the previous version, when I commit the changes to the server mutation, I only got the ":delta" in the params. Something like that: {:delta {:tx/set {[:event/by-id 2] {:event/title Title 22}}}}

baris20:02:23

Now, I get get the hole "Forms" Data (Elements, etc.) but the delta is also included in the map, so it works for the moment. Here is an example output from the params value in the server mutation: {:form {:db/id 1, :event/title Title 12, :event/desc Desc 1, :untangled.ui.forms/form {:elements/by-name {:event/title {:input/name :event/title, :input/default-value , :input/placeholder , :input/css-class input, :input/validate-on-blur? true, :input/type :untangled.ui.forms/text}, :event/desc {:input/name :event/desc, :input/default-value , :input/placeholder , :input/css-class input, :input/validate-on-blur? true, :input/type :untangled.ui.forms/text}, :db/id {:input/name :db/id, :input/type :untangled.ui.forms/identity}}, :ident [:event/by-id 1], :origin {:event/title Title 1, :event/desc Desc 1, :db/id 1}, :subforms [], :validation {:event/title :valid, :event/desc :unchecked, :db/id :valid}}}, :delta {:form/updates {[:event/by-id 1] {:event/title Title 12}}}}

tony.kay20:02:41

off of clojars or a checkouts on develop?

baris20:02:51

I didn't had the chance to dig into the code....but I guess there is something not ok with the diffing stuff?

tony.kay20:02:54

Cause that should have been fixed already

baris20:02:16

checkout/fork the develop branch and installed it to my local mvn repos

tony.kay20:02:18

the delta is there, just that param wasn't getting dissoc'd on the ast

tony.kay20:02:44

I did fix that, and it should be on develop, unless someone caused a regression with a bad merge in git

tony.kay20:02:51

(possibly me)

baris20:02:54

my version is from ur last commit 35c19d40192c0664165aa445c4766c6992b74553 “updated docs a bit"

tony.kay20:02:05

yes, it got dropped. Commit 20c6ab was right

tony.kay20:02:21

something I did caused git to lose it's mind. I think I did a rebase, and that probably screwed it

baris20:02:40

ok…no stress checkin whenever u r ready

tony.kay20:02:53

thanks for the note. I didn't cover it with a test

baris20:02:17

it’s still hot and new stuff....relax

tony.kay20:02:50

@baris what do you think of getting rid of the delta key?

tony.kay20:02:09

just raising the whole mess in params to be the map of changes

tony.kay20:02:34

I'm renaming the keys already, so anyone using it is going to have to touch some code

tony.kay20:02:49

(taking liberties with pre-release status 😉 )

baris20:02:25

would make it easier

tony.kay20:02:46

yeah, then you could just destructure at params

baris20:02:47

as long as nothing else needs to be in the params

tony.kay20:02:00

It could always be added as another key in the map

baris20:02:58

for me its totaly ok to get rid of the delta key

baris20:02:35

the only interesting keys are the updates, new-entity and so on....so delta is unnecessary

baris21:02:58

Sometimes I use the state threadding in a mutation/swap! to modify the app-state like this

baris21:02:12

integrate-ident! caused some unclear errors about IDeref...it took me a while to figure out that I misused`intgrate-ident!`. I think it is an easy fix to check if the "state" is an atom or not and then use swap! or not in integrate-ident. Could probably safe a lot of time for others when they are in the same situation.

baris21:02:42

What do you think @tony.kay ?

tony.kay21:02:55

I like composition. Let's think about this a bit. The integrate-ident! function was meant to be a helper for post-mutation loads that wanted to target data into the app state. Um, I think I'd rather do this (which is similar): 1. Make the ! form have an atom assertion, so it will fail fast with a good error message 2. make a non ! form that takes state as a map and returns new state, and re-factor (1) to be it/use it

tony.kay21:02:27

then you have both, but not API confusion about the ! meaning "internal mutation lives here"

tony.kay21:02:44

You want to do it, or you want me to?

baris21:02:57

I can go for that

baris21:02:45

still have some headache on how to integrate image-upload into the forms or in general to upload a file within untangled/om.next. Would appreciate to have some more hints on that in the near future.

tony.kay21:02:20

Did you look at the implementation of the image upload in untangled-ui?

tony.kay21:02:40

basically we just did a base64 encode of the uploaded element and encoded that into a mutation param

tony.kay21:02:00

all comms go through POST

tony.kay21:02:14

so transit can just carry it that way

baris21:02:20

ahh…had the same idea about base64 encoding…wasn’t sure about the “best way to do"

tony.kay21:02:22

(encode via javascript)

tony.kay21:02:39

don't know if it is the best idea either 😉

tony.kay21:02:43

but it works for now

baris21:02:11

jap 👍 will try it in the next days

tony.kay21:02:01

a mutation to send the file (that also updates app state to show uploading spinner), followed by a follow-on remote-read in the same Om transaction with a post mutation that hides the upload...use a UI tempid in the mutation, and include that tempid in the follow-on remote read.

tony.kay21:02:15

that wasn't very clear 😕

tony.kay21:02:29

Here are the ideas: 1. You're going to want to know the identity of the uploaded thing from the server. Use tempids for that. You make some kind of thing in your app state that HAS that UI generated tempid, and send that tempid with the upload. The server mutation sends back the tempid remapping. Now you know the ID of the upload on the server

tony.kay21:02:33

2. A single transaction can include both reads and writes. Reads in Untangled use the load mutation. So something like this:

(om/transact! this `[(upload ~{:base64 data :filename "boo" :id some-om-tempid}) (uc/load { ...query with same tempid...})])

tony.kay21:02:28

3. The network stack of Untangled sends writes before reads (no sense in reading stale data). The response from writes WILL REWRITE tempids in the network queue

tony.kay21:02:53

So, your follow-on load will have the right real ID...so you could query for status about the image.

tony.kay21:02:10

You could also use a return value handler to handle app state changes you might want to make after the upload is done

tony.kay21:02:36

Remember your UI is still going to be unblocked during all of that. So you might need to set app state to prevent leaving the page/submission until upload is complete.

tony.kay21:02:00

File upload control for forms that standardizes all of this is on the TODO list

baris21:02:29

thanks a lot. That sounds like a good way and plan to do the upload. I’ll try it

baris21:02:53

and yeah....to have a file upload control would perfect

tony.kay21:02:36

The follow-on load might not be needed...you know the ID of the thing, but the follow-on read would be a way of sequencing a post-mutation to trigger app state changes.

tony.kay21:02:47

same with the return value handler

tony.kay21:02:53

the latter is probably better

tony.kay21:02:07

there really isn't anything to load if you handle the return value

tony.kay21:02:35

@baris just pushed an updated to develop that fixes your regression and has a bit more doc. Still working on it though