I'm trying to add Apollo to an app. I'll be using it for fetching data, and want to follow best practices and use the new API (as of Apollo 2.5) to store local UI state as well.
I've been looking at these docs, but their UI state is simpler than the one I want to implement.
I want to port over a pattern I've been using in Redux apps, where the values of many UI elements are stored centrally. In Redux, I've had a reducer object which stored my UI values, and looked like this:
{
dropdowns: {
someDropdown: [{ index: 0, value: 'Selected Value' }]
},
checkboxes: {
someCheckbox: true
}
}
As in, different types of elements were represented as objects for which each key was the unique ID of a UI element, and the value varied based on the element type.
I'm also open to a flattened version of the above, where there are no sub-categorizations by UI element type.
I also had a separate reducer storing the state of some UI elements, eg:
{
openDropdownId: 'someDropdown',
openModalId: null
}
Crucially, it seems, this data includes objects whose keys are not predictable. I'm both unsure how to type this using
gqland unsure how to fetch this data efficiently (see bottom of question).
I've tried reproducing this with Apollo Client, but have run into a ton of errors. Here's my client setup:
For, say, a dropdown, the idea is that
stateshere stores open/closed state , whereasvaluesstores info about the selected value.
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import gql from 'graphql-tag';
const typeDefs = gql`
extend type UI {
states: Object
values: Object
}
`;
const defaults = {
ui: {
__typename: 'UI',
states: {},
values: {}
}
};
const cache = new InMemoryCache();
const client = new ApolloClient({
cache,
resolvers: {},
typeDefs
});
console.log({ defaults });
cache.writeData({ data: defaults });
export default client;
Then I use that client like so:
<ApolloProvider client={client}>
<App />
</ApolloProvider>
And here's an example of a query that throws an error:
const QUERY = gql`
{
ui @client {
states
values
}
}
`;
The errors I'm seeing are:
Uncaught Invariant Violation: Missing selection set for object of type undefined returned for query field states
That error shows up in the Query component.
I also get two warnings (probably one for states and one for values) that:
Missing field __typename in {}
Do I need to structure my data differently to query it like this?
Follow-up question: If a component has a UID, it'd be nice to be able to query its values like:
const QUERY = gql`
{
ui @client {
states {
${uid}
}
values {
${uid}
}
}
}
`;
Instead of getting all UI values and then finding the appropriate one in the component.
That throws an error, however:
Syntax Error: Invalid number, expected digit but got: "d".
Is there a way to perform such a query, or a better way to handle all this? Although this data structure might not be idiomatic, it does seem that Apollo should support this for filtered queries, no?