Fork me on GitHub
#om
<
2017-01-09
>
dottedmag07:01:46

Has anyone tried to store core.async state inside Om state? The motivation is the following -- I'd like to model interactions as a synchronous program, not "someone called me, I reacted, stored state somewhere in shared space for the next handler to pick it up", following what Rich was demonstrating in core.async talk. This works ok while webpage is open, but if it is refreshed, there is a problem -- core.async state is lost, so all in-progress interactions are stopped and, worse, all data they have updated in the state (progress indicators, dialogs - whatever) are out-of-sync. It'd be marvelous to be able to serialize core.async state to be able to restart these computations on refresh (some of them won't be restartable, like XHR communications, but at least things waiting for a user input will be).

fenton10:01:24

@dottedmag you might need to store stuff to html5 storage to survive across refreshes

dottedmag11:01:56

@fenton That's the least of my worries

hlolli12:01:44

@dottedmag have you ruled out serialize the old state after refresh by using the component's lifecycles?

hlolli13:01:45

If I may rant a bit, then it annoys me hell alot when a nested component is able to get its remote queried data when it lacks its correct composed queries. Only to lose it after some local-state changes. It takes long time to analyze the problem. Seems to me in om that if the query is wrong, then no data should be passed down the tree, but sometimes does so anyway.

dottedmag13:01:12

@hlolli not sure I understood the question.

danielstockton13:01:51

@hlolli well it depends in what way it's 'wrong', probably

dottedmag13:01:58

I'd like to avoid keep current interaction state in the Om state / components state, or my UI code will degenerate into "event handlers".

hlolli13:01:01

@danielstockton imagine a child that implements a remote read that is not implemented in root component, the child gets what it asks for despite no property is being passed down, only for the property of the child behaveing unstable later on. To me, the read should never appear in this child's component. Maybe go into the app-state and stop there.

danielstockton13:01:34

i see, that sounds like what was happening to @nha earlier, I guess it gets passed something by the reconciler automatically when the root query is first triggered?

danielstockton13:01:10

does sound undesirable, maybe there is a good reason

hlolli13:01:20

yes it gives the false idea that all components are equal (able to query the app-state) when in fact they are not, root component is alpha and omega in om to the app-state.

hlolli13:01:16

@dottedmag react.js feels often like a chain of "reactive" event handlers. But I see what you mean.

dottedmag13:01:25

@hlolli Looks like I'm going to say "whatever is not finished when the page is reload gets discarded", which means stable app state has no running go-blocks. It's simple, and probably not even that bad.

mavbozo13:01:45

@anmonteiro ah, i was wrong to worry too much. since js is single threaded, parse & transact can not happen at the same time. thanks for the question

danielstockton13:01:15

Does anyone have a technique for triggering remote reads after novelty has been merged from a remote? Still struggling with this one.

danielstockton13:01:45

I need something like a 'post-merge' hook

tmulvaney14:01:35

@danielstockton why can't you fetch everything in the remote call?

danielstockton14:01:46

first call is to login and get authorization token, second call is to fetch data after receiving the token

danielstockton14:01:18

im not using clojure or om on the server-side which might make things sub-optimal but have no choice at the moment

jfntn14:01:18

@danielstockton: you can customize the reconciler's merge function for that

danielstockton14:01:33

@jfntn that's something I tried, but merge has to return a map with certain keys, i don't know how i can trigger the read to occur after the merge without hacks like using setTimeout

danielstockton14:01:18

i.e. if i transact any reads in merge, it will trigger before the state has updated with the token from the first request

jfntn14:01:16

@danielstockton yes our is hacky too, uses setTimeout 0 to call something like (did-merge-remote reconciler query params result) but it let’s us say (defmulti did-merge-remote :app/user [reconciler _ _ {:keys [token]}] (om/transact! reconciler [(user/do-protected {:token ~token})])`

danielstockton14:01:10

ah cool, i feel slightly less bad about doing that then, if it works with 0 thats not too bad

jfntn14:01:59

The implementation is more involved than I’d like since the merge function will get the whole query, you’ll need to use om/query->ast to get all the query nodes in order to dispatch on the individual disptach-keys , reduce over that and recombine if you want to do any modifications to the merge results

jfntn14:01:08

Would love to find a simpler solution

danielstockton14:01:45

yeah, i might be able to get away with something simpler since this is a one off at login and i always redirect to the same place

danielstockton14:01:00

it actually works with just this:

(js/setTimeout
     (fn []
       (om/transact! reconciler (om/get-query Dashboard)))
     0))
thanks a lot @jfntn, been struggling with that for a while

jfntn14:01:14

Cool! We used to do something simple too, let me know if you run into issues with this in the future

peeja15:01:17

@danielstockton There's also no reason you can't call the callback multiple times from your send. You can get the first data, pass it to the callback, then get the second data right there and then pass that to the callback.

danielstockton15:01:48

right @peeja, didn't think of that but makes sense, thanks

danielstockton15:01:07

then i don't need a setTimeout

danielstockton15:01:32

i also control my preloader from there, so easier to avoid a slight flicker that im having at the moment 👍

peeja15:01:45

That's what I'm planning to do, as I'm about to be mapping deep queries to a set of REST APIs: often, I'll need to make a call for one thing that will return some ids, then make more calls using those ids, etc.

danielstockton15:01:59

i see, interesting

iconara15:01:32

it's an interesting discussion you're having, I'm a newbie at om.next and I've been struggling with the right way to load data from a rest-ish api. do you have any good pointers? blogs, example apps?

danielstockton15:01:03

im working with a django/python backend and decided it was easier to write a om next query parser in python rather than map to rest from the client

danielstockton15:01:28

i wrote it as a pypi lib, might open source it soon although its quite bespoke to my needs and leaves a lot to the user

peeja15:01:32

Yeah, if you can pass full queries on to the backend, all the better. We're trying to avoid migrating too much too fast. 🙂

peeja15:01:06

@iconara Not yet, but I'll probably write something when this is working 🙂

iconara15:01:26

that would be great

ag18:01:44

is there a way in the read method to access component scope (this), of the component that “invoked” it. So for example I can pull om/get-ident on it?

ag19:01:17

is there any good way to pull ident of a specific component class in a read method?

sova-soars-the-sora21:01:18

@ag could you elaborate a bit on your question?

ag21:01:16

In a read method I need to pull data from the state, data based on ident of another component class. Let’s say I pass params {:ids [:id-1 :id-2]} now I need to retrieve data from the state related to this ids, but the way the normalization set is defined in the component’s ident; e.g. if ident says [:data/by-id :id:] I can hardcode that in the read method. Saying (get-in @state [:data/by-id current-id])`. But then sometime later someone decides to change ident specification. let’s say it becomes [:backend-data/by-id], now my hardcoded piece in read method blows up in runtime.

ag21:01:36

So I want to read the specific ident of the component in the read method

sova-soars-the-sora22:01:05

@ag Ah, so if I understand you correctly, you want to be able to use Idents that might be named differently in the future?

ag22:01:36

@sova right, I need to pull specific ident of a specific component class in a read method

ag22:01:03

hey guys, I’m once again struggling to set params for a query, so I can feed that query to the parser. doing (query->ast) then modifying ast and running (ast->query) does not getting me right stuff

ag22:01:24

can you remind me the right incantation here?

ag23:01:00

eh, another probably annoying, noob , if I have a query, with subquery, with a subquery and that component of that nested subquery has ident, at what point I can expect om.next to normalize data? what kicks off the normalization?

ag23:01:50

can idents be nested? like queries?

ag23:01:00

or I’m just being silly?