Open dko-slapdash opened 4 years ago
I think this would be really useful to help with data masking
could this be the same as (rough code):
const useFragment = (fragment, id) => useApolloClient().readFragment({ id, fragment })
?
@rajington it's close except readFragment
doesn't return an Observable
so the result won't update when the store data changes.
Is there any solution to observe a fragment change in the cache?
Here's our tracking issue for the implementation of useFragment
in Apollo Client v3.5 (the next minor version).
Is there any solution to observe a fragment change in the cache?
To answer @itdhsc's question, yes, but useEffect
complicates things, so it's better to keep the details hidden behind an abstraction like useFragment
.
I should have a PR open soon using my useFragment-hook
branch.
I was playing around with an implementation earlier this week here: https://github.com/NerdWalletOSS/apollo-cache-policies/pull/33 for useFragment
and a collection filter useFragmentWhere
. If folks have feedback/suggestions feel free to take a look
Why not to add useEntity also?
const entity = useEntity(User:${id}
)
Why not to add useEntity also?
const entity = useEntity(
User:${id}
)
I think because you still need to specify a fragment to indicate which fields you want to read. For performance it's inefficient to return all fields by default. Then if you need to pass a fragment anyways, you can just use useFragment
.
@danReynolds for performance it is much more inefficient to map entity into fragment, I guess problem here could be with proper typing in typescript.
@danReynolds for performance it is much more inefficient to map entity into fragment, I guess problem here could be with proper typing in typescript.
I was thinking of performance related to the reactive changes. If you return the entire object, Apollo will think you're dependent on all of those fields so if any of them change, your component or other places where you're subscribed to that object will update.
The reactive part of Apollo client is built around invalidation based on field dependencies
I am definitely very interested in this API at the apolloCache
layer which is necessary for this to work at the React hook layer.
We have a bunch of cases (ie regulatory requirements) where we want to fire analytics / auditing events when entities change in the cache. This would be a super powerful pattern.
Either being able to watchFragment
similar to watchQuery
or something like this:
apollo.watchTypes({
// __typename
Trip: {
onAdd: (trip) => {
// ... do something
},
onUpdate: (oldTrip, newTrip) => {
// ... do something
},
onDelete: (trip) => {
// ... do something
},
}
})
I am definitely very interested in this API at the
apolloCache
layer which is necessary for this to work at the React hook layer.We have a bunch of cases (ie regulatory requirements) where we want to fire analytics / auditing events when entities change in the cache. This would be a super powerful pattern.
Either being able to
watchFragment
similar towatchQuery
or something like this:apollo.watchTypes({ // __typename Trip: { onAdd: (trip) => { // ... do something }, onUpdate: (oldTrip, newTrip) => { // ... do something }, onDelete: (trip) => { // ... do something }, } })
Yea that's what I made https://github.com/NerdWalletOSS/apollo-cache-policies for a while back initially.
@danReynolds that looks interesting and solves some of my goals, but not all of them. Also would love to see this on native as well.
Question about useFragment(), is it supposed to support adding the fragments in our queries?
ie, child component with a fragment written in it:
export const DriverCardFragment = gql`
fragment DriverCardFragment on Driver {
id
firstName
lastName
driverName
createdAt
updatedAt
}
`;
I'd like to use that fragment in the query itself, so that I can keep the data logic scoped to the child component and not have to worry about updating parent components or affecting other children, like so:
const DRIVER_GRID_QUERY = gql`
query QueryDrivers() {
drivers: queryDrivers() {
/// fields
nodes {
id
...DriverCardFragment
}
}
}
`;
If I write this query and fragment in Apollo studio, it works just fine, but if I try and send the same query with the spread fragment in my app using Apollo Client, I get an error:
"The specified fragment DriverCardFragment
does not exist."
The hook portion of the child component, in case I'm doing something wrong:
const { complete, data } = useFragment_experimental({
fragment: DriverCardFragment,
fragmentName: 'DriverCardFragment',
from: {
__typename: 'Driver',
id: driverId,
},
returnPartialData: true,
optimistic: false,
});
@Dmo16 as of now, there is no automatic registration of that fragment, so you'd need to import it and include in the query like you normally would when not using useFragment
.
import { DriverCardFragment } from './path/to/fragment'
const DRIVER_GRID_QUERY = gql`
query QueryDrivers() {
drivers: queryDrivers() {
# fields
nodes {
id
...DriverCardFragment
}
}
}
${DriverCardFragment} # <-- Ensure this is added to the query
`;
That's the missing piece in your code right now to make it work. Hope this helps!
I just found out about microsoft's apollo-react-relay-duct-tape
package. Looks promising but I haven't tried it. Definitely posting it here as it might help some of us with this.
https://microsoft.github.io/graphitation/docs/apollo-react-relay-duct-tape/use-lazy-load-query
https://github.com/microsoft/graphitation
Anyone had any success with it?
Hi.
There is useQuery(), but there is no useFragment() which would allow to watch some fragment in the cache and re-render accordingly.
An example use-case would be the following: