Skip to content

Commit aed39a7

Browse files
committed
simpleCollections: both, field policy subscribtion madness
1 parent a3be012 commit aed39a7

File tree

8 files changed

+96
-115
lines changed

8 files changed

+96
-115
lines changed

client/src/App.css

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ body {
66
}
77

88
.todo-list {
9-
list-style-type: none;
109
padding: 0;
1110
width: 100%;
1211
margin-top: 2rem;

client/src/App.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import TodoInput from './TodoInput';
33
import TodoList from './TodoList';
44
import './App.css';
55

6-
export default function App() {
6+
export default function App(props) {
77
return (
88
<>
99
<TodoInput />
10-
<TodoList />
10+
<TodoList {...props} />
1111
</>
1212
);
1313
}

client/src/Todo.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default function Todo({ id, task, completed }) {
2525
};
2626

2727
return (
28-
<div className="todo-list__element">
28+
<div key={id} className="todo-list__element">
2929
<div
3030
className="todo-list__text"
3131
style={{ textDecoration: completed ? 'line-through' : 'none' }}

client/src/TodoList.js

+60-36
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,77 @@
11
import React from 'react';
22
import Todo from './Todo';
3-
import { useQuery } from '@apollo/client';
3+
import { useQuery, useApolloClient } from '@apollo/client';
44
import { GET_TODOS, SUBSCRIBE_TODOS } from './graphql';
55

66
export default function TodoList() {
7+
const client = useApolloClient();
78
const { subscribeToMore, data, error, loading } = useQuery(GET_TODOS);
8-
if (error) return <p className="alert">{error.message}</p>;
9-
if (loading) return <p className="alert">loading...</p>;
10-
const { todos } = data;
11-
subscribeToMore({
12-
document: SUBSCRIBE_TODOS,
13-
updateQuery: (prev, { subscriptionData }) => {
14-
if (!subscriptionData.data) return prev;
15-
if (!subscriptionData.data.listen.relatedNode) {
16-
return {
17-
todos: prev.todos.filter(
18-
(todo) => todo.id !== subscriptionData.data.listen.relatedNodeId
19-
),
20-
};
21-
} else {
22-
let incomingTodo = prev.todos.find(
23-
(todo) => todo.id === `${subscriptionData.data.listen.relatedNodeId}`
24-
);
25-
if (incomingTodo) {
9+
// if (error) return <p className="alert">{error.message}</p>;
10+
// if (loading) return <p className="alert">loading...</p>;
11+
React.useEffect(() => {
12+
const unsubscribe = subscribeToMore({
13+
document: SUBSCRIBE_TODOS,
14+
updateQuery: (prev, { subscriptionData }) => {
15+
if (!subscriptionData.data) return prev;
16+
if (!subscriptionData.data.listen.relatedNode) {
2617
return {
27-
todos: prev.todos.map((todo) =>
28-
todo.id === incomingTodo.id
29-
? { ...todo, completed: !todo.completed }
30-
: todo
31-
),
18+
todosConnection: {
19+
...prev.todosConnection,
20+
nodes: prev.todosConnection.nodes.map((todo) =>
21+
todo.id === subscriptionData.data.listen.relatedNodeId
22+
? { ...todo, deleted: true }
23+
: todo
24+
),
25+
},
3226
};
3327
} else {
34-
return {
35-
todos: [
36-
...prev.todos,
37-
{
38-
id: subscriptionData.data.listen.relatedNodeId,
39-
...subscriptionData.data.listen.relatedNode,
28+
let incomingTodo = prev.todosConnection.nodes.find(
29+
(todo) =>
30+
todo.id === `${subscriptionData.data.listen.relatedNodeId}`
31+
);
32+
if (incomingTodo) {
33+
return {
34+
todosConnection: {
35+
...prev.todosConnection,
36+
nodes: prev.todosConnection.nodes.map((todo) =>
37+
todo.id === subscriptionData.data.listen.relatedNodeId
38+
? {
39+
...todo,
40+
completed:
41+
subscriptionData.data.listen.relatedNode.completed,
42+
}
43+
: todo
44+
),
4045
},
41-
],
42-
};
46+
};
47+
} else {
48+
return {
49+
todosConnection: {
50+
...prev.todosConnection,
51+
nodes: [
52+
...prev.todosConnection.nodes,
53+
{
54+
id: subscriptionData.data.listen.relatedNodeId,
55+
...subscriptionData.data.listen.relatedNode,
56+
},
57+
],
58+
},
59+
};
60+
}
4361
}
44-
}
45-
},
46-
});
62+
},
63+
});
64+
return unsubscribe;
65+
}, [subscribeToMore, client.cache]);
4766

67+
if (loading) return <h1>loading</h1>;
68+
if (error) return <h1>error</h1>;
69+
const {
70+
todosConnection: { nodes },
71+
} = data;
4872
return (
4973
<div className="todo-list">
50-
{todos.map((todo) => {
74+
{nodes.map((todo) => {
5175
return <Todo key={todo.id} {...todo} />;
5276
})}
5377
</div>

client/src/Todo_uhoh.js

-68
This file was deleted.

client/src/graphql.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ import { gql } from '@apollo/client';
33
/* get all todos */
44
export const GET_TODOS = gql`
55
query GetTodos {
6-
todos {
7-
id
8-
task
9-
completed
6+
todosConnection {
7+
nodes {
8+
completed
9+
id
10+
task
11+
deleted @client
12+
}
1013
}
1114
}
1215
`;
@@ -30,6 +33,7 @@ export const UPDATE_COMPLETED = gql`
3033
updateTodoById(input: { patch: { completed: $completed }, id: $id }) {
3134
todo {
3235
id
36+
completed
3337
}
3438
}
3539
}

client/src/index.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,30 @@ const client = new ApolloClient({
4141
typePolicies: {
4242
Query: {
4343
fields: {
44-
todos: {
45-
merge: false,
44+
todosConnection: {
45+
merge: true,
46+
},
47+
},
48+
},
49+
TodosConnection: {
50+
fields: {
51+
nodes: {
52+
merge(incoming, { readField, cache }) {
53+
return incoming.map((todo) =>
54+
readField('deleted', todo)
55+
? cache.evict(cache.identify(todo)) && {}
56+
: todo
57+
);
58+
},
59+
},
60+
},
61+
},
62+
Todo: {
63+
fields: {
64+
deleted: {
65+
read(deleted = false) {
66+
return deleted;
67+
},
4668
},
4769
},
4870
},

server/postgraphile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module.exports = postgraphile(
2626
watchPg: true,
2727
graphiql: true,
2828
enhanceGraphiql: true,
29-
simpleCollections: 'only',
29+
simpleCollections: 'both',
3030
graphileBuildOptions: { pgOmitListSuffix: true },
3131
classicIds: true,
3232
pluginHook,

0 commit comments

Comments
 (0)