Sync new todos
In the previous section we made a button that shows up only when there are new public todos in the database. Now lets make this button functional i.e. on pressing this button, newer todos should be fetched from the backend, synced with the local todos and the button must be dismissed.
Go to src/screens/components/Todo/LoadNewer.js
, import gql
and define the query to fetch newer todos.
+ import gql from 'graphql-tag';+ const FETCH_NEW_TODOS = gql`+ query ($lastId: Int){+ todos (+ order_by: {+ id: desc+ },+ where: {+ _and: {+ is_public: { _eq: true},+ id: { _gt: $lastId}+ }+ }+ ) {+ id+ title+ is_completed+ created_at+ is_public+ user {+ name+ }+ }+}+`;
Import the FETCH_TODOS
query so that we can read its local cache and update it with newer todos.
+ import { FETCH_TODOS } from './Todos';
Also wrap the LoadNewerButton
component in withApollo
so that we receive the client
prop.
+ import { withApollo } from 'react-apollo';// LoadNewer.jsexport default withApollo(LoadNewerButton);
Let us initialise a new state variables that contain the button text and loading.;
Now, whenever the button is pressed, we wish to make the FETCH_NEW_TODOS
query and add the data to cache. Lets write a function that does just that.
const LoadNewerButton = ({ isPublic, ...props}) => {const [buttonText, setButtonText] = React.useState('New tasks have arrived');const [loading, setLoading] = React.useState(false);+ const fetchNewerTodos = async () => {+ const { client } = props;+ const data = client.readQuery({+ query: FETCH_TODOS,+ variables: {+ isPublic,+ }+ });+ const lastId = data.todos[0].id;+ setLoading(true);+ const resp = await client.query({+ query: FETCH_NEW_TODOS,+ variables: { lastId }+ });+ setLoading(false);+ if (resp.data) {+ const newData = {+ todos: [ ...resp.data.todos, ...data.todos]+ }+ client.writeQuery({+ query: FETCH_TODOS,+ variables: {+ isPublic,+ },+ data: newData+ });+ props.toggleShow();+ }+ }if (!show) {return null;}return (<TouchableOpacitystyle={styles.pagination}+ onPress={fetchNewerTodos}disabled={loading}>{loading ?<CenterSpinner /> :<Text style={styles.buttonText}>{buttonText}</Text>}</TouchableOpacity>)}
With this, your fully functional realtime todo app is ready.
- Build apps and APIs 10x faster
- Built-in authorization and caching
- 8x more performant than hand-rolled APIs