untangled

NEW CHANNEL: #fulcro
tony.kay 2017-02-21T03:54:34.003613Z

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

👍 1
cjmurphy 2017-02-21T04:42:21.003615Z

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.

grant 2017-02-21T14:06:31.003617Z

@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.kay 2017-02-21T17:12:03.003618Z

@cjmurphy I know exactly what that is

tony.kay 2017-02-21T17:12:23.003619Z

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

tony.kay 2017-02-21T17:12:32.003620Z

In user.clj there is a start-figwheel function

tony.kay 2017-02-21T17:13:24.003621Z

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

tony.kay 2017-02-21T17:13:51.003622Z

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.kay 2017-02-21T17:13:57.003623Z

Here is the approximate fix:

tony.kay 2017-02-21T17:14:09.003624Z

(usiung figwheel sidecar 0.5.9):

tony.kay 2017-02-21T17:14:21.003625Z

(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.kay 2017-02-21T17:14:44.003626Z

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

cjmurphy 2017-02-21T19:15:18.003627Z

@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.kay 2017-02-21T20:04:25.003630Z

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

tony.kay 2017-02-21T20:06:09.003631Z

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

cjmurphy 2017-02-21T20:12:51.003632Z

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.kay 2017-02-21T20:13:08.003633Z

slash

tony.kay 2017-02-21T20:13:13.003635Z

script/figwheel.clj

tony.kay 2017-02-21T20:13:17.003636Z

in your settings for the run config

tony.kay 2017-02-21T20:13:35.003637Z

oh, that is not a main class

tony.kay 2017-02-21T20:13:43.003638Z

it is a parameter to REPL startup

tony.kay 2017-02-21T20:13:57.003639Z

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

2017-02-21T20:15:40.003640Z

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.kay 2017-02-21T20:15:58.003641Z

it is all WIP 🙂

tony.kay 2017-02-21T20:16:02.003642Z

as in right now

tony.kay 2017-02-21T20:16:19.003643Z

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

2017-02-21T20:16:34.003644Z

ok 🙂

tony.kay 2017-02-21T20:16:46.003645Z

I'll push an update in a few hours

2017-02-21T20:16:54.003646Z

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

tony.kay 2017-02-21T20:17:06.003647Z

great. let's fix 'em

2017-02-21T20:17:16.003648Z

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.

2017-02-21T20:17:26.003649Z

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

2017-02-21T20:17:37.003650Z

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.kay 2017-02-21T20:18:13.003651Z

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

2017-02-21T20:18:31.003652Z

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

tony.kay 2017-02-21T20:18:50.003653Z

that would be more interesting 🙂

2017-02-21T20:19:00.003654Z

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}}}}

2017-02-21T20:19:23.003655Z

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.kay 2017-02-21T20:19:41.003656Z

off of clojars or a checkouts on develop?

2017-02-21T20:19:51.003657Z

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

tony.kay 2017-02-21T20:19:54.003658Z

Cause that should have been fixed already

2017-02-21T20:20:16.003659Z

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

tony.kay 2017-02-21T20:20:18.003660Z

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

tony.kay 2017-02-21T20:20:44.003661Z

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

tony.kay 2017-02-21T20:20:51.003662Z

(possibly me)

tony.kay 2017-02-21T20:21:50.003663Z

weird

2017-02-21T20:21:54.003664Z

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

tony.kay 2017-02-21T20:22:05.003665Z

yes, it got dropped. Commit 20c6ab was right

tony.kay 2017-02-21T20:22:21.003667Z

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

tony.kay 2017-02-21T20:22:23.003668Z

argh

2017-02-21T20:22:40.003669Z

ok…no stress checkin whenever u r ready

tony.kay 2017-02-21T20:22:53.003670Z

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

tony.kay 2017-02-21T20:22:56.003671Z

😕

2017-02-21T20:23:17.003672Z

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

tony.kay 2017-02-21T20:25:50.003674Z

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

tony.kay 2017-02-21T20:26:09.003675Z

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

tony.kay 2017-02-21T20:26:34.003676Z

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

tony.kay 2017-02-21T20:26:49.003677Z

(taking liberties with pre-release status 😉 )

2017-02-21T20:27:25.003678Z

would make it easier

tony.kay 2017-02-21T20:27:46.003679Z

yeah, then you could just destructure at params

2017-02-21T20:27:47.003680Z

as long as nothing else needs to be in the params

tony.kay 2017-02-21T20:28:00.003681Z

It could always be added as another key in the map

2017-02-21T20:28:58.003682Z

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

2017-02-21T20:29:35.003683Z

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

2017-02-21T21:04:58.003685Z

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

2017-02-21T21:06:12.003687Z

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.

2017-02-21T21:06:42.003688Z

What do you think @tony.kay ?

tony.kay 2017-02-21T21:09:55.003689Z

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.kay 2017-02-21T21:10:27.003690Z

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

tony.kay 2017-02-21T21:10:44.003691Z

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

2017-02-21T21:10:57.003692Z

I can go for that

tony.kay 2017-02-21T21:11:04.003693Z

cool

2017-02-21T21:13:45.003694Z

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.kay 2017-02-21T21:14:20.003695Z

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

tony.kay 2017-02-21T21:14:40.003696Z

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

tony.kay 2017-02-21T21:15:00.003697Z

all comms go through POST

tony.kay 2017-02-21T21:15:14.003698Z

so transit can just carry it that way

2017-02-21T21:15:20.003699Z

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

tony.kay 2017-02-21T21:15:22.003700Z

(encode via javascript)

tony.kay 2017-02-21T21:15:39.003701Z

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

tony.kay 2017-02-21T21:15:43.003702Z

but it works for now

2017-02-21T21:16:11.003704Z

jap 👍 will try it in the next days

tony.kay 2017-02-21T21:18:01.003705Z

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.kay 2017-02-21T21:18:10.003706Z

hm

tony.kay 2017-02-21T21:18:15.003707Z

that wasn't very clear 😕

tony.kay 2017-02-21T21:19:29.003708Z

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.kay 2017-02-21T21:21:33.003709Z

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.kay 2017-02-21T21:22:28.003711Z

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.kay 2017-02-21T21:22:53.003712Z

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

tony.kay 2017-02-21T21:23:10.003713Z

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

tony.kay 2017-02-21T21:23:36.003714Z

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.kay 2017-02-21T21:24:00.003715Z

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

2017-02-21T21:25:29.003716Z

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

2017-02-21T21:25:53.003717Z

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

tony.kay 2017-02-21T21:26:36.003718Z

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.kay 2017-02-21T21:26:47.003719Z

same with the return value handler

tony.kay 2017-02-21T21:26:53.003720Z

the latter is probably better

tony.kay 2017-02-21T21:27:07.003721Z

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

tony.kay 2017-02-21T21:49:35.003722Z

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