Our Tech Journal
  • Introduction
  • Overview
    • Introduction
  • Javascript
    • JS Runtime, Env Context, Scopes, Hoisting & Execution Cycle, var/let/const, this
    • Javascript Runtime Env
      • Event loops
    • What are WebVitals
    • Module Patterns in JS - CommonJS, AMD and ES6 classes
    • Lexical Environment in JS
    • var vs let/const
    • Temporal Dead Zone (TDZ)
    • Execution Context
    • 'this' keyword
    • undefined value in JS
    • Function expressions vs Function statements
    • Javascript Code Execution
    • Closures
    • JS : Object Oriented Programming
    • Prototypal Inheritance
      • Creating Object in Javascript
    • NaN
    • Objects
      • Ways to create
      • ways to check if Object is empty
      • Object's own properties
    • use strict mode
    • typeof vs instanceof
    • Promise
    • localStorage and SessionStorage
    • Event handlers
    • Event bubbling
    • Event Delegation
    • XHR Request
    • Promise Error: Catch vs Error Function in Then
    • Immutability
    • Useful Code samples
    • window, document, screen
    • window.innerheight, outer height, screen.height
    • JS Design Patters
    • Interview Questions
    • Encapsulation - Module Patterns in JS
    • Redesigning services using Entity framework approach
  • JS Functions
    • JS Array - Slice vs Splice
  • PWA
    • What is PWA
  • ES6
    • Sets
    • Maps
    • spread vs destructure operator
  • Web
    • http / https
    • CORS
    • CSRF
    • XSS Attack
    • What is SPA
    • Semantic Elements in HTML
  • Angular 4
    • Angular vs React
    • Change Detection
    • Lazy Loading of modules
    • Preloading
    • AOT Compilation
    • Route Guards
    • Shared Modules
    • Tree Shaking
    • LifeCycle Hooks
    • ngRx
    • Observables
    • Observable vs Subject
      • BehaviorSubject
    • Observables vs Promises
    • Builtin Directives
      • Temp
      • Structural Directives
        • ngForTemp
        • ngSwitch
        • ngFor
        • ngIf
      • Attribute Directives
        • temp
        • ngClass
        • ngStyle
    • Routing
      • Routing in Angular
      • Setting up basic routing
      • routerLink and routerLinkActive
      • router.navigate and ActivatedRoute
      • Route Params as Observables
      • redirectTo
      • relativeTo
      • pathMatch
      • ActivatedRoute
      • Routing in Angular
      • Passing Data with Route
      • Route Parameters
    • Intercept HTTP request
    • Custom Directives
    • Communication between components
    • Angular Modules
    • Reactive Forms
    • Unit Testing
      • TestBed and component fixture
      • Testing HttpClient requests
      • Testing fakeAsync
  • GraphQL
    • Introduction
    • Server
    • Client Side
    • GraphQL in Angular
    • Queries
      • temp
      • query with parameters
      • aliases
      • fragments
      • @include directive
      • @skip directive
      • variables
      • Inline Fragments
  • CSS
    • What is Box model?
    • display: block, inline or inline-block
    • CSS Selector: Combinators
    • CSS Pseudo-classes
    • CSS Pseudo-elements
    • CSS3 Filter
    • CSS3 Transitions
    • Media Queries
    • Flex vs Grid
    • CSS 3 Grids
    • What is Flexbox?
    • position: relative vs absolute
  • SASS
    • Mixins
    • Lists
    • Maps
  • RxJS
    • throttle vs debounceTime
    • distinctUnitChange
    • reduce vs scan
  • Typescript
    • Typeguards
    • Pattern Matching with Typescript
    • TS Decorators
    • Using LINQ in TS
  • NodeJS
    • NodeJS Security Checklist
    • What is Node.js
  • REACT
    • React - VDOM - Under the hood
    • Synthetic events in React
    • Routing - React Router 4
    • React Custom hook
    • Higher-Order Component
    • REDUX
    • Redux Thunk vs Redux Saga
    • forceUpdate()
    • Storing Data in React
    • Error Handling
    • React Context
    • How React-Native works
    • refs
    • Server-side Rendering
    • Jest setup file
    • React-test-renderer
    • Lifecycle
    • React Testing Library
    • React Query
  • JWT
    • What is JWT and How it works
Powered by GitBook
On this page
  • Client side setup (Apollo GraphQL client)
  • Create NetworkInterface and ApolloClient
  • Setting up React components to work with GraphQL
  • Options to update Client after Mutation
  • Refetch
  • Store Update
  • GraphQL Subscriptions
  • Optimistic UI
  1. GraphQL

Client Side

Client side setup (Apollo GraphQL client)

Apollo GraphQL client manages the data store (cache) and network requests from our client application to the GraphQL server.

Create NetworkInterface and ApolloClient

For our front-end React application to communicate to GraphQL server, we first setup the network interface. Then we set up the ApolloClient providing it the this graphQL's network interface.

// imports....
import { ApolloClient, createNetworkInterface } from 'apollo-client';

const networkInterface = createNetworkInterface({
  uri: '/graphql'
});

export const client = new ApolloClient({ networkInterface });

Setting up React components to work with GraphQL

For our React components to work with Apollo GraphQL Client, we need to wrap the react component inside a Higher-order Component called graphQL provided by react-apollo library. This High-order component would pass down the response from GraphQL server's query or mutation to the wrapped react component.

For a component that is calling a query, the response will be sent as data object:

{ data: { ...responseData, loading: true/false, error: {} }

Note the loading property available in the data object to indicate if the data query is in progress or over.

For a component that is calling a mutation, the graphQL will pass down a mutate object that we can use to call the mutation on GraphQL server

{ mutate: { variables from mutation response } }

React component using a query

React component using a mutation

import React from 'react';
import { gql, graphql } from 'react-apollo';

// Component function
class UpdateUserEmailReactComponent extends React.Component {
  { mutate } = this.props;

  const updateUserEmail = (evt) => {
    if (evt.keyCode === 13) {
      mutate({ 
        variables: { 
             { 
                userEmail: { evt.target.value } 
             } 
        }
      })
      .then( res => {
        // email updated successfully
      });
    }
  };
  return (
    <input
      type="text"
      placeholder="Enter Email"
    />
    <button type="button" onclick="updateUserEmail">Update Email</button>
  );
};


const updateUserEmailMutationQuery = gql`
  mutation mutateUserEmail($userId: String!, $email: String!) {
    UserEmail(id: $userId, email: $email) {
      id
      email
    } 
  }
`;

type UserEmail {
  email: string 
  id: string
}

const UpdateUserEmailGraphQLComponent = graphql(
  updateUserEmailMutationQuery
)(UpdateUserEmailReactComponent);


export default UpdateUserEmailGraphQLComponent;

Options to update Client after Mutation

To update the client state after a mutation, we have three options: 1. Use mutate objects 'Refetch' property to specify the queries to rerun that could be affected by the mutation 2. Use mutate objects 'Update' method to update the client state based on the mutation result 3. Use GraphQL subscriptions to notify clients about updates.

Refetch

  // updateUserEmail.ts
  ...
  import { userDetails } from './user/UserDetails';

  ...
  // make email mutate
  mutate(
     variables: { 
                userEmail: { evt.target.value } 
     },
     refetchQueries: [ {query: userDetails} ]  //this would refetch the userDetails 
  )

Store Update

In the above approach, the mutation actually costed the client two trips to server. The first one for mutation and then second one for the refetching the affected data. This approach may not get us best user experience for clients with low network latency.

For such scenarios, the graphQL component's mutation object exposes us an Update function that gets called when the mutation completes. The update function provides us the store (cached data store of Apollo Client) object. We can use to this Update function to construct a payment type transaction object and push it the transactionsList available in store.

    // updateUserEmail.ts
    ...

    ...
    // make email mutate
    mutate(
      variables: { 
         userEmail: { evt.target.value } 
      },
      update: (store, { data }) => {
        { email } = data;

        const userDetails = store.readQuery({ query: userDetailsQuery });

        userDetails.email = email;
        store.writeQuery({ query: userDetailsQuery, userDetails });
     }
  )

GraphQL Subscriptions

This is useful when multiple clients need to be updated when some data gets mutated.

Optimistic UI

PreviousServerNextGraphQL in Angular

Last updated 5 years ago

https://dev-blog.apollodata.com/tutorial-graphql-mutations-optimistic-ui-and-store-updates-f7b6b66bf0e2