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
?
@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
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.
load-data
on [{:x [:y]}]
will do the same
as will [{:x [:y]} :z]
. In the latter case, nothing appears at :z
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.
@tony.kay +1 for moving the marker it would make my life a bit easier
@tony.kay: ah great thank you that makes sense
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?
@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.
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
@gardnervickers which version are you running of untangled-client?
0.5.8-SNAPSHOT
it’s a checkout from master
Oh ok, I don’t think you want to use :ident
that is to make a join on something. (it makes load-data
basically load-field
)
What should I do if I want to “refresh” the data on a component then?
At least that is how I interpreted it
Don’t you want to use :refresh
?
I meant refresh as in re-run the components data fetch
@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
You can just run a refresh from a user action (a mutation)?
I am sorry I don’t really get your question @gardnervickers
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 assoc
ing the load marker onto the key nil
.
Sorry, butchered that ^
@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
Nope, neither
Hm
https://github.com/untangled-web/untangled-client/blob/master/src/untangled/client/impl/data_fetch.cljs#L290
It’s because I have an :ident
I think
@mitchelkuijpers: the refresh keyword tells the UI what to re-render, it doesn't trigger a new data fetch on its own
(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.
Yeah but I still wouldn't expect it to show up at the top level of app state
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
Yes, otherwise normalization could fail
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 …}
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 😄
Not sure I understand. Is you query [:a :b :c]
or [{[:my :ident] [:a :b :c]}]
because if you are using the :ident
parameter in your data load, then the latter is what is being formed
Yea that’s correct, the latter is the query that’s being answered by the server
Yeah I’m not sure that data fetch supports that
although you’re right, based on the doc string and syntax it seems like it should
let me double check
I mean it does correctly fetch the data, just the marker is placed incorrectly
yeah I believe it correctly fetches the data, I’m just not sure that the marker/normalization plumbing anticipates that use case
Oh gotcha ok
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
it assumes that a load-field is happening, whereas your case is closer to to load-fields (plural)
so the field
key may be empty but the query
key may be present
makes me think that instead of having a special field
key in the data state, that we should just put it under query
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?
Sure
thanks
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?
@gardnervickers probably not
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
At the moment we're primarily using load markers for fields, and the global :ui/loading-data (which can be queried from any component)
I'm not convinced it makes sense to make load-data
work with markers at all, to be honest
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)
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
Sounds good, thanks for the well thought out reply, as always it's appreciated!
sure...I'll change your issue to a feature request (enhancement)
I think I see a way to make the API clearer...others are going to want similar things
I am working with devcards is there a particular example that would be helpful?
?
The entire tutorial?
🙂
I am almost at the point where I would like to run some mocked server transaction
Look at the Putting It Together section
Aha thnx
I should really do that tutorial lol
it has you write a full-stack example using a real server, but runs the UI in dev cards
Oh that is exactly what I am looking for
Awsum
yeah, the app state viewing is so sweet
I like putting a delay into the server, just so I can watch the network magic 🙂
Though it reveals a few "unclean" things in the current implementation...some cruft gets left around
harmless, but ugly
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
But the printing of the app state alone saves a lot of time
assuming your app state isn't too big
Yeah but we mostly try to create small modulair parts
and then put it together in the application
Really cool stuff
thanks. I am really loving how it is coming together...still finding little improvements to make, but man it is nice to work with
note 0.5.8-SNAPSHOT @mitchelkuijpers
I have not released 0.5.8 yet, and it is needed to get the app state display in devcards
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?
yes
see Tutorial
hm...actually, @mahinshaw did you merge the advanced UI stuff yet?
Untangled (because it uses Om Next) is 100% compatible with vanilla React
Here's an example using Victory:
I can't speak for specific other React libs....mostly the problem you might hit are build problems with module support
not specific to Untangled/Om
Some js libs are packaged in a way that makes them harder to "get at"
Maria has done work on that, but it isn't well-documented: https://github.com/clojure/clojurescript/wiki/Google-Summer-of-Code-2015
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
@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
when the library does already require react, it's possible to bundle excluding the react itself?
@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
).humm, nice, I didn't knew about that feature
thanks @gardnervickers , I'll be trying that later today 🙂
@tony.kay No, I haven’t. Ill get it in today
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.
wooo :advanced
optimized builds fixed itself
it use to be broken last time I tried it 2 months ago
nice to know, @jasonjckn . You should probably thank @anmonteiro
@tony.kay I put up a PR for the advanced ui stuff
@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