-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Q: How would I update the Apollo store after creation? #180
Comments
Ooh, this is something I've been thinking about but haven't documented, as part of #172 (writing up reactivity designs). I really want to make this work for you, so that we can expand it into a first-class feature of Apollo Client. Can you give me a bit more info? Specifically:
Because Apollo Client has the ability to normalize data by ID, I think we can come up with something awesome. The ID normalization is implemented and tested, just not turned on in the public API -- I suspect making that feature available will help a lot. |
The data is a structured JSON response, the structure itself does not match the schema, but of course the data keys/values do. Incoming Data Query General get ToDo query The ID normalization seems like it might work for me. const fragment = gql`
fragment node on ToDo {
id,
title
published
createdBy
}
`;
const result = {
id: "urn:lsid:572d058c9932c8bb19416853",
title: "NewToDo",
published: 1462568332749,
createdBy: "e8e73f40-ba74-102b-8a1d-c574ebd76cf3"
}; BTW: Are you using _.deepclone (in that unit test) due to your test case reusing the result obj, if not at its always required, may be better placed within the writeFragmentToStore function for convenience. |
Exactly. I ran into an error before where I was accidentally mutating the result object, and that made the test pass even though the code was wrong. So nothing to worry about - just a test artifact. |
OK so it looks like you should be able to use the fragment you wrote and use Going to set that up asap. |
Sort of an on-topic tangent, but wouldn't a streaming API into Apollo-Client be outside the GraphQL spec? Scott |
Sure, but the spec applies to what the server does, not how the client uses that data. |
The alternative is to make an additional query for data we already have on the client, just to populate the apollo store on the client. |
Yep, basically firing a fake query result event! |
I guess I was getting my impression from the GraphQL introduction the Facebook team did last year. I seem to remember them saying they explored a streaming capability and deciding to not go that direction for Facebook's purposes (in their GraphQL API). You are right, the spec doesn't even mention how the data is transported or ingested by either the client or the server actually. 👍 to a streaming capability. Could HTTP2 push also be something to use as the transport? https://en.wikipedia.org/wiki/HTTP/2_Server_Push Scott |
I was just running into this as well. In our case, we can subscribe to a CouchDB
then i can use the |
This might be useful for mixing with Meteor pubsub? Instead of putting data from DDP in minimongo, put it in Redux? |
Exactly! And yes, this could also be a way to put Meteor pubsub data into the Apollo store if one desired. I think this might call for a new API on ApolloClient to inject external data, just to make the approach standardized. |
Thanks—I have some code working that updates existing items in the store. Still have a follow up question, though: if the result of my query is a list of items, and I have a new item (rather than an update to an existing item), how should that be handled? Do I have to refetch the query, or is there a way to let I see the |
Yeah that's definitely one thing we need to figure out - it's not enough to just insert the new object, you also need to update any lists or references to include it:
This may return:
Now when we insert a new todo item we need to make sure it's inserted into that Here's one option: const newTodoItem = {
id: '7',
content: 'This is a task!',
completed: false,
};
const query = gql`
{
todoList(id: 4) {
todos { id, content, completed }
}
}
`
const result = readQueryFromStore({ query, store });
// Now, we have a query-shaped data blob, let's add the new item
result.todoList.todos.push(newTodoItem);
state = writeQueryToStore({
result,
query,
store,
dataIdFromObject,
}); This way, we update the store without actually dealing with the store format. What do you think? |
Where does |
Oh yeah that is what it should be. The "store" parameter in those functions is pretty misnamed... All of the code I posted would go in the reducer. |
Still working through your example, but I think it actually needs I'll give this a shot…and let you know how it goes. Thanks again! |
Yeah, sorry - maybe I should put it into a gist or something so that I can update it more easily... |
I'm not sure where the best place to put thoughts/notes on reactivity is, but since I've been discussing it here so far, I'll continue. Just wanted to share a few things I've been running in to and thinking here. An issue that I just ran in to with this (and is perhaps immediately obvious, but took some time for me to realize) is that if you do a
as in the example above, it won't update the results for a query like
and vice-versa. This, of course, makes sense: at some point, you'd have to have the entire logic of the GraphQL server to satisfy something like
That said, it seems like some functions that would allow us to do some of the following would be really helpful:
Some of this is maybe already done in the |
I have a question which is maybe very simple but I can't find the answer anywhere else (I am very new to apollo, thank for all the work achieved so far!) I have a websocket streaming data into my store and I want to update my components without refetching data. I used this thread to achieve it but my component connected to apollo client by mapQueryToProps won't update: const state = store.getState().apollo;
const data = readQueryFromStore({
store: state.data,
query: myQuery,
});
/*
mutate the data
insert some element and delete others
...
*/
state.data = writeQueryToStore({
result: data,
query: myQuery,
store: state.data,
dataIdFromObject,
}); Is there any redux actions I need to dispatch in order to update components connected with mapQueryToProps to this query? Is there something I am missing? |
You need to do this in a Redux reducer. Redux doesn't have any way of telling when state has changed, so you should fire a custom action and do this inside the reducer. Also, you can use a new feature we just added, Although I'm not sure |
Should be easy now with #766 |
If anyone is coming to this in the future, I see that |
Clarify what is "Query" key in `customResolvers` example
I'm receiving real-time data from another channel (WS).
I was hoping to update the apollo store much like queries and mutations, but I'm not sure how to go about this.
Is there an option or approach which creates a mutation with some data but not to actually send that mutation to the server?
UseCase:
Apollo Store > Query > Get All Comments > store gets updated > React UI updates
New Comments arrive via a web socket
My Issue
I would like to update my React Component(s) (via ApolloClient & ReactApollo).
I guess this pattern is not specific to apollo-client, and more general to any graphQL client using store (such as redux)
The text was updated successfully, but these errors were encountered: