Fork me on GitHub
#untangled
<
2016-10-11
>
gardnervickers01:10:28

If I use data-fetch/load-data from within a component, the doc’s say it places a loading marker in place of the components props, but I’m not seeing that. Should I be querying for :ui/loading-data on the component like with data-fetch/load-field?

tony.kay05:10:03

@gardnervickers We need to improve the docs on that a bit. There are a couple of things. By default load-data does put a load marker in place, but in the place of the data being queried. load-field will put the marker in place of the field being loaded. Since load-data loads data into the top-level app state, the marker actually is placed at the first property in the query at the root

tony.kay05:10:11

So, (load-data this ‘[:x]) will put the load marker as if you did an assoc-in at [:x :ui/fetch-state] in the app state.

tony.kay05:10:52

load-data on [{:x [:y]}] will do the same

tony.kay05:10:17

as will [{:x [:y]} :z]. In the latter case, nothing appears at :z

tony.kay05:10:58

we should probably extend this functionality a bit to allow you to place the load marker in a spot of your choosing, since you might be doing a post mutation to move it into place after the load.

mitchelkuijpers08:10:57

@tony.kay +1 for moving the marker it would make my life a bit easier

gardnervickers09:10:15

@tony.kay: ah great thank you that makes sense

dilvan11:10:42

Does Untangled support using DataScript with Om Next? I know it doesn't support DataScript queries (they are slow), but can I still use a DataScript db?

gardnervickers12:10:14

@tony.kay For my data-fetch/load-data, it’s sufficient to just supply and :ident and :marker true, right? I’m seeing the data load marker being placed under {nil {:ui/fetch-state {…}} in the app state instead of on the first element of my query.

gardnervickers13:10:06

It appears that when you’re loading component has an ident set and it’s a load-data (without a field specified), then (data-field state) is nil here. https://github.com/untangled-web/untangled-client/blob/master/src/untangled/client/impl/data_fetch.cljs#L292

mitchelkuijpers13:10:23

@gardnervickers which version are you running of untangled-client?

gardnervickers13:10:01

it’s a checkout from master

mitchelkuijpers13:10:26

Oh ok, I don’t think you want to use :ident

mitchelkuijpers13:10:50

that is to make a join on something. (it makes load-data basically load-field)

gardnervickers13:10:15

What should I do if I want to “refresh” the data on a component then?

mitchelkuijpers13:10:24

At least that is how I interpreted it

mitchelkuijpers13:10:43

Don’t you want to use :refresh ?

gardnervickers13:10:41

I meant refresh as in re-run the components data fetch

ethangracer13:10:09

@dilvan: no, you must use Om's default db format with untangled. But we have added a ton of structure to make it easier to use than stock Om next. For example, you don't have to build a read parser

mitchelkuijpers13:10:12

You can just run a refresh from a user action (a mutation)?

mitchelkuijpers13:10:03

I am sorry I don’t really get your question @gardnervickers

gardnervickers13:10:28

The issue I’m running into is that from what was mentioned above by Tony, a load-data on a component should place the loading marker on the first element of the components query. With that, a component with a query [:a :b :c], load-data on that should swap out :a for the loading data marker map (so I can use it with lazily-loaded, etc..). What I’m seeing instead of that is the function that places the marker is not swapping out the value of :a for the load marker, but is associng the load marker onto the key nil.

gardnervickers13:10:45

Sorry, butchered that ^

ethangracer13:10:38

@gardnervickers: are you parameterizing the query? Or using a post-mutation? We had a bug like that a couple weeks ago, thought that we had fixed it

ethangracer13:10:11

@mitchelkuijpers: the refresh keyword tells the UI what to re-render, it doesn't trigger a new data fetch on its own

gardnervickers13:10:46

(data-field state) would return nil because I don’t have a field I want to load. Presumably this should be the first key in the query.

ethangracer13:10:15

Yeah but I still wouldn't expect it to show up at the top level of app state

ethangracer13:10:49

In any case I'm not sure that the Ident and field parameters are intended to be used separately -- I think we assume that they are always used together

ethangracer13:10:52

Yes, otherwise normalization could fail

gardnervickers13:10:39

Just to confirm what I’m seeing because you mentioned the “top level of app state”. For query [:a :b :c], I see (under the proper ident in my table when using :ident) {:a … :b … :c … nil <load-marker>} instead of {:a <load-marker> :b … :c …}

gardnervickers13:10:57

I’m fine writing my own version of load-data if this is not the intended use for it too, just wanted to make sure 😄

ethangracer13:10:36

Not sure I understand. Is you query [:a :b :c] or [{[:my :ident] [:a :b :c]}]

ethangracer13:10:52

because if you are using the :ident parameter in your data load, then the latter is what is being formed

gardnervickers13:10:10

Yea that’s correct, the latter is the query that’s being answered by the server

ethangracer13:10:33

Yeah I’m not sure that data fetch supports that

ethangracer13:10:00

although you’re right, based on the doc string and syntax it seems like it should

ethangracer13:10:08

let me double check

gardnervickers13:10:14

I mean it does correctly fetch the data, just the marker is placed incorrectly

ethangracer13:10:17

yeah I believe it correctly fetches the data, I’m just not sure that the marker/normalization plumbing anticipates that use case

ethangracer13:10:14

yeah. not sure if it’s a bug or not but it appears to be an issue with the data-path function that you linked me

ethangracer13:10:43

it assumes that a load-field is happening, whereas your case is closer to to load-fields (plural)

ethangracer13:10:04

so the field key may be empty but the query key may be present

ethangracer13:10:35

makes me think that instead of having a special field key in the data state, that we should just put it under query

ethangracer13:10:21

I’ll have to do some digging to see how / if to fix this but don’t have time at the moment. @gardnervickers can you file an issue and copy this little 5 line rant into it?

gardnervickers14:10:08

So with load-field, we replace the value of the field we’re trying to load with the load marker. Does it make sense for load-data to replace the data at that “level” of the tree with the load marker? Similar to running load-field from the parent on the join that is created from our component’s query?

tony.kay14:10:37

there is no "level" in the database, and your load-data might be loading something that you have to post-mutate into place...meaning that your query might be unrelated to the triggering UI

tony.kay14:10:08

At the moment we're primarily using load markers for fields, and the global :ui/loading-data (which can be queried from any component)

tony.kay14:10:35

I'm not convinced it makes sense to make load-data work with markers at all, to be honest

tony.kay14:10:19

Query for [[:ui/loading-data '_]] in any component and you can use that to show a busy indicator...but typically you'd show that in some globally visible location. If you want a component-specific marker, just put that in your app state manually (e.g. place a :ui/loading true in the state of the component you're working with, and have your post mutation remove it)

tony.kay15:10:00

The load marker support in Untangled is a really simple convenience, and if we can make the API more generally useful we will, but all of these cases are actually pretty simple to implement with the base primitives we've supplied

gardnervickers15:10:17

Sounds good, thanks for the well thought out reply, as always it's appreciated!

tony.kay15:10:34

sure...I'll change your issue to a feature request (enhancement)

tony.kay15:10:52

I think I see a way to make the API clearer...others are going to want similar things

mitchelkuijpers15:10:27

I am working with devcards is there a particular example that would be helpful?

tony.kay15:10:45

The entire tutorial?

mitchelkuijpers15:10:51

I am almost at the point where I would like to run some mocked server transaction

tony.kay15:10:04

Look at the Putting It Together section

mitchelkuijpers15:10:17

I should really do that tutorial lol

tony.kay15:10:18

it has you write a full-stack example using a real server, but runs the UI in dev cards

mitchelkuijpers15:10:49

Oh that is exactly what I am looking for

tony.kay15:10:57

yeah, the app state viewing is so sweet

tony.kay15:10:17

I like putting a delay into the server, just so I can watch the network magic 🙂

tony.kay15:10:43

Though it reveals a few "unclean" things in the current implementation...some cruft gets left around

tony.kay15:10:51

harmless, but ugly

mitchelkuijpers15:10:25

Yeah I want to make myself create stuff in devcards and then just drop it in the application, it feels like a way better approach to developing

mitchelkuijpers15:10:45

But the printing of the app state alone saves a lot of time

tony.kay15:10:55

assuming your app state isn't too big

mitchelkuijpers15:10:44

Yeah but we mostly try to create small modulair parts

mitchelkuijpers15:10:53

and then put it together in the application

mitchelkuijpers15:10:10

Really cool stuff

tony.kay15:10:34

thanks. I am really loving how it is coming together...still finding little improvements to make, but man it is nice to work with

tony.kay15:10:36

I have not released 0.5.8 yet, and it is needed to get the app state display in devcards

dilvan15:10:54

Is there a way to use Material Design components with untangled (for instance, http://www.material-ui.com)? Can I also reuse javaScript components written for react.js?

tony.kay15:10:28

see Tutorial

tony.kay15:10:42

hm...actually, @mahinshaw did you merge the advanced UI stuff yet?

tony.kay15:10:05

Untangled (because it uses Om Next) is 100% compatible with vanilla React

tony.kay15:10:06

Here's an example using Victory:

tony.kay15:10:01

I can't speak for specific other React libs....mostly the problem you might hit are build problems with module support

tony.kay15:10:34

not specific to Untangled/Om

tony.kay15:10:50

Some js libs are packaged in a way that makes them harder to "get at"

tony.kay15:10:36

Maria has done work on that, but it isn't well-documented: https://github.com/clojure/clojurescript/wiki/Google-Summer-of-Code-2015

gardnervickers15:10:49

We’ve been using NPM and webpack to make a bundle placing the libraries we need on the window object. Then, we generate the externs based on the external calls we use instead of generating them for the entire Javscript library

wilkerlucio15:10:55

@gardnervickers can you share some of the configurations used for it? I felt the need to that a couple times but didn't got into the trouble of actually trying

wilkerlucio16:10:18

when the library does already require react, it's possible to bundle excluding the react itself?

gardnervickers16:10:36

@wilkerlucio This is an example of our webpack config file

const webpack = require('webpack');
const path = require('path');

const BUILD_DIR = path.resolve(__dirname, 'resources', 'public', 'js');
const APP_DIR = path.resolve(__dirname, 'src', 'js');

const config = {
    entry: `${APP_DIR}/main.js`,
    module: {
        loaders: [
            { test: /\.jsx?$/, loaders: ['babel-loader'], exclude: /node_modules/ },
            { test: /\.css$/, loader: "style-loader!css-loader"},
            { test: /.(png|woff(2)?|eot|ttf|svg)(\?[a-z0-9=\.]+)?$/, loader: 'url-loader?limit=100000' },
            { test: /\.less$/, loader: "style!css!less"}
        ]
    },
    output: {
        path: BUILD_DIR,
        filename: 'bundle.js'
    },
    resolve: {
        extensions: ['', '.js']
    },
    externals: {
        "react": "React",
        "react-dom": "ReactDOM",
        "react-bootstrap": "BS",
        "react-addons-shallow-compare": "React.addons.shallowCompare"
    },
    node: {
        fs: "empty"
    }
};

module.exports = config;
The important part is the externals, which allow us to supply our own React/ReactDOM implementations (from cljsjs).

wilkerlucio16:10:12

humm, nice, I didn't knew about that feature

wilkerlucio16:10:54

thanks @gardnervickers , I'll be trying that later today 🙂

mahinshaw17:10:03

@tony.kay No, I haven’t. Ill get it in today

tony.kay19:10:52

I've started working on issue #43 regarding load markers. Our data load code could use some refactoring and cleanup, which I'm also going to do. Just in case anyone out there is working on a patch that would conflict.

jasonjckn23:10:19

wooo :advanced optimized builds fixed itself

jasonjckn23:10:28

it use to be broken last time I tried it 2 months ago

tony.kay23:10:14

nice to know, @jasonjckn . You should probably thank @anmonteiro

mahinshaw23:10:49

@tony.kay I put up a PR for the advanced ui stuff

tony.kay23:10:35

@mahinshaw just sent in a section on integrating React js components with Om/Untangled. Now available in the tutorial: http://untangled-web.github.io/untangled/tutorial.html#!/untangled_tutorial.M10_Advanced_UI