Closed dustinfarris closed 7 years ago
Yes you can! This is a pattern we use rather regularly with Cashay/GraphQL in our application Action.
What we do is use Cashay's @cached
operator to query locally. Cashay will return an object along the shape of our requested query. If it's the first time the route is accessed, the query will return with the proper shape but with empty data. When the mutation fires, the mutation handler can return the data for the query, and the @cached
query will then return the subfields as requested.
For some example, see how admins can login as other users or how we authenticate and update user preferences.
@jordanh Interesting! @cached
looks really neat. I'll have to play with this to figure out how to make it work for me.
Thanks for open-sourcing action. That project has exponentially increased my GraphQL on-boarding velocity—truly grateful.
@jordanh this is working for me! (in Ember, but should look similar):
// looking for an item that doesn't exist yet
const newItemQuery = `
{
item @cached(type: "Item") {
id
name
}
}
`;
const stateToComputed = () => {
const { data: { item } } = cashay.query(newItemQuery, {
op: 'createItem',
mutationHandlers: {
// Registering so that Cashay selects an id
createItem() { }
},
resolveCached: {
// We don't actually care about this yet
item: () => { }
},
});
return { item };
};
const CreateItem = Component.extend({
createItem: task(function *(changeset) {
yield cashay.mutate('createItem', {
variables: {
// `changest.change` will be something like: `{ name: 'My New Item' }`
item_details: changeset.get('change')
}
}).then(response => { // waiting for an id...
if (!response.error) {
// "itemCreated" is an upstream action that will redirect to a the detail page
this.sendAction('itemCreated', response.data.createItem.id);
}
});
}).drop(), // drop prevents this task from being called more than once
layout: hbs`
<!-- This is really cool because I can pass the empty "item" object from
the cached query to the form component! -->
{{create-map-form
changeset=(changeset item)
submit=(perform createItem)
}}
`
});
export default connect(stateToComputed)(CreateItem);
What I think might be possible, is to actually create the item in the background with empty data, then when the user clicks "Create" what's really happening is an update. Then the user doesn't have to wait for an id to be redirected because it's already there. Many ways to skin a cat here I'm sure.
This looks awesome! Nice work @dustinfarris!
Scenario:
Is it possible to have Cashay ask for a minimum of an "id" or something?