Closed jameslaneconkling closed 7 years ago
@jameslaneconkling sorry for the delay, I didn't have notifications turned on for the repo.
Yes, you can access the deref'd path from the output JSON via the $__path
key. So in your example, you can get it from userModel.$__path
.
I've been going back and forth on whether to move the $ props to a public namespace or not. So far, I've only had to use them in library-internals, so I've kept them $. Thoughts?
@trxcllnt ah excellent, $__path
is exactly what I was looking for. Specifically, if I make a get or call request with refs in the response, I can get the absolute paths for those nodes via something like (in my case) falcorJSON.json.search.<searchId>.matches.<searchResultIdx>.$__path
.
Just thinking as I go here, but I'd guess there are at least as many good reasons for keeping this out of the public namespace, as there are for exposing it. The more common case for an end user, I'd guess, would be navigating through/iterating over the result data and ignoring metadata like $__path
. But for cases where you are interested in the absolute/dereferenced path, $__path
works, and b/c it's not enumerable, a user doesn't have to worry about accidentally iterating over it.
I vaguely remember a conversation on the Netflix falcor issue tracker about accessing or filtering out graph metadata, so that if you're iterating through your falcorJSON
response, you don't have to worry about manually avoiding node metadata.
On a related note, are there available ways to iterate over a falcorJSON
result set? B/c it's not a POJO, utils like R.map
don't work, and Object.keys(falcorJSON)
returns the f_meta
key. It appears it does inherit methods from the Array prototype (from here?), but they don't work as expected, e.g. falcorJSON.map(x => x)
always returns an empty array.
I vaguely remember a conversation on the Netflix falcor issue tracker about accessing or filtering out graph metadata, so that if you're iterating through your falcorJSON response, you don't have to worry about manually avoiding node metadata.
Yeah, there aren't a lot of good options here. Falcor needs the JSON to have some metadata to know how to deref new Models, but we also don't want to pollute the output namespace too much. In the new mutable cache walk, I can get away with creating a second prototype Object and sticking the metadata on there, because the sub-tree diff'ing we get via hashcodes makes get so fast in the 80% case, we have a ton of breathing room to do extra allocations.
Alternatively, I've added support for a new branchSelector
function, which will be called with the FalcorJSON
instance as each branch is created. The JSON argument will already have the metadata attached, so you can use it as the prototype for your own instances if you want. You can define it once when you create the root Model (via new Model({ branchSelector: (json) => /* do your thing */ })
.
On a related note, are there available ways to iterate over a falcorJSON result set? B/c it's not a POJO, utils like R.map don't work, and Object.keys(falcorJSON) returns the f_meta key. It appears it does inherit methods from the Array prototype (from here?), but they don't work as expected, e.g. falcorJSON.map(x => x) always returns an empty array.
So this is my probably-too-clever solution to make it easier to work with lists. If you request a range of integers along with the length, we can use the native Array methods on the JSON result. This is especially handy when combined with the falcor-react-schema/withFragment
higher-order component (still a work-in-progress port to separate the older falcor-react-redux/container
HOC logic from Redux), which fetches a component's query and reduces over the resulting JSON until the query stabilizes. I haven't had time to properly document/blog about everything, but here's the general idea:
import { withFragment } from 'falcor-react-schema';
function MyList({ items = [] }) {
return <ul>{ items.map((item) => <MyListItem {...item}>) }</ul>
}
MyList = withFragment({
fragment: ({ items = [] }) => `{
items: {
length, [0...${items.length}]: {
whatever, item, keys, you, want
}
}`
})(MyList);
export { MyList }
Alright, super helpful--thanks.
If you request a range of integers along with the length, we can use the native Array methods on the JSON result
Ah, OK. I actually did have a length
property on my collection, however w/ boxValues()
enabled, so that length looks like {$type: "atom", value: 357, $size: 51}
rather than 357
, the map method does not work. (but I can confirm that when I disable boxValues, it does work as expected).
RE: falcor-react-schema
I haven't seen that published anywhere. Is it public? I have been looking at falcor-react-redux
, which looks like it's done a great job of abstracting over falcor and redux (a hard problem (for me, at least), given that falcor is asynchronous, and the redux store is synchronous). Reminds me of Relay a bit. Hadn't started running w/ it yet, as I'm still working on decoding it, but your above example gives a good hint at how it works. Any plans to publish docs?
Curious to know if you have a public api to access a node's absolute path (aka it's resolved/dereferenced path). I was surprised Netflix didn't expose this easily, except through acrobatics like
I noticed that you stored path metadata under the JSONGraph's private
f_meta.abs_path
property. Is there any way to access this property?