<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Uku Lele</title>
    <description>The latest articles on DEV Community by Uku Lele (@uku_lele).</description>
    <link>https://dev.to/uku_lele</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1067797%2Ffa5d019c-c641-4570-87cc-512827422e1e.jpg</url>
      <title>DEV Community: Uku Lele</title>
      <link>https://dev.to/uku_lele</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/uku_lele"/>
    <language>en</language>
    <item>
      <title>Open local html file in incognito window of Google Chrome browser</title>
      <dc:creator>Uku Lele</dc:creator>
      <pubDate>Thu, 22 Jun 2023 10:50:35 +0000</pubDate>
      <link>https://dev.to/uku_lele/open-local-html-file-in-incognito-window-7ld</link>
      <guid>https://dev.to/uku_lele/open-local-html-file-in-incognito-window-7ld</guid>
      <description>&lt;p&gt;We will open a local HTML file in an incognito window of the browser Google Chrome.&lt;br&gt;
Environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Windows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Google Chrome&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sequencing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Chrome in incognito mode
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Uy0D70Qo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lqzpxj3ezv8mg988u3sv.jpg" alt="Image description" width="800" height="490"&gt;
&lt;/li&gt;
&lt;li&gt;Open Windows Explorer with HTML file
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7RRTU4_g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3pg3j5fcgbv12mllxev4.jpg" alt="Image description" width="565" height="158"&gt;
&lt;/li&gt;
&lt;li&gt;Begin to drag HTML file
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o4F2DEzA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9z5bxogkz15itzn0vdup.jpg" alt="Image description" width="546" height="178"&gt;
&lt;/li&gt;
&lt;li&gt;Switch to Chrome window (Alt + Tab)
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--02DU64uf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzacenbvkkbd7j8q45d7.jpg" alt="Image description" width="800" height="488"&gt;
&lt;/li&gt;
&lt;li&gt;Drop HTML file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f-Dy8Lul--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v1sze5tnqk7fkb03gi4r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f-Dy8Lul--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v1sze5tnqk7fkb03gi4r.jpg" alt="Image description" width="800" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading the article.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Simple full-stack application with GraphQL, Apollo 4, Node.js, Express, React, MongoDB, TypeScript</title>
      <dc:creator>Uku Lele</dc:creator>
      <pubDate>Sat, 29 Apr 2023 06:55:52 +0000</pubDate>
      <link>https://dev.to/uku_lele/graphql-apollo-4-nodejs-express-react-mongodb-typescript-4mga</link>
      <guid>https://dev.to/uku_lele/graphql-apollo-4-nodejs-express-react-mongodb-typescript-4mga</guid>
      <description>&lt;p&gt;We will create a simple full-stack application. On the client (in the browser), we will display information about users. We will be able to add a user to the database and get user information by user id. On the client side, we will use React, GraphQL, Apollo Client, TypeScript. On the server side we will use GraphQL, Apollo  Server 4, TypeScript, Node.js, Express. The data will be stored in the database MongoDB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required Software&lt;/strong&gt;&lt;br&gt;
The computer must have the following software installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/en/download" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.mongodb.com/try/download/community" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Beginning&lt;/strong&gt;&lt;br&gt;
Create a new directory for your app:&lt;br&gt;
&lt;code&gt;mkdir ragnemt-app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server&lt;/strong&gt;&lt;br&gt;
Create a &lt;em&gt;server&lt;/em&gt; directory under the &lt;em&gt;ragnemt-app&lt;/em&gt; directory:&lt;br&gt;
&lt;code&gt;cd ragnemt-app&lt;br&gt;
 mkdir server&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Go to the &lt;em&gt;server&lt;/em&gt; directory, create a &lt;code&gt;package.json&lt;/code&gt; file&lt;br&gt;
 and install Apollo Server and GraphQL:&lt;br&gt;
&lt;code&gt;cd server&lt;br&gt;
 npm init -y&lt;br&gt;
 npm i @apollo/server graphql&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Install express, body-parser, @types/cors and @types/body-parser:&lt;br&gt;
&lt;code&gt;npm i express body-parser @types/cors @types/body-parser&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install Apollo data source, mongoose for MongoDB:&lt;br&gt;
&lt;code&gt;npm i apollo-datasource-mongodb mongoose&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install TypeScript:&lt;br&gt;
&lt;code&gt;npm i --save-dev typescript @types/node&lt;/code&gt;&lt;br&gt;
Create a &lt;code&gt;tsconfig.json&lt;/code&gt; file in the &lt;em&gt;server&lt;/em&gt; folder. Add the following configuration to the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "compilerOptions": {
        "rootDirs": [
            "src"
        ],
        "outDir": "dist",
        "lib": [
            "es2020"
        ],
        "target": "es2020",
        "module": "esnext",
        "moduleResolution": "node",
        "esModuleInterop": true,
        "types": [
            "node"
        ],
    },
    "include": ["src"],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;em&gt;src&lt;/em&gt; directory under the &lt;em&gt;server&lt;/em&gt; directory.&lt;br&gt;
&lt;code&gt;mkdir src&lt;br&gt;
cd src&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create a types.ts file in the _src _directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ObjectId } from 'mongodb';

export interface UserDocument {
  _id?: ObjectId
  username: string
  password: string
  email: string
}

export interface Context {
  loggedInUser: UserDocument
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a schema and convert it to a model. Create a &lt;em&gt;models&lt;/em&gt; directory in the &lt;em&gt;src&lt;/em&gt; directory. Create a &lt;code&gt;user.ts&lt;/code&gt; file in the &lt;em&gt;models&lt;/em&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose, { Schema } from "mongoose";
import { ObjectId } from 'mongodb';

const userSchema = new Schema({
  _id: ObjectId,
  username: String,
  password: String,
  email: String,
});

export const User = mongoose.model("user", userSchema);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;em&gt;dataSources&lt;/em&gt; directory in the &lt;em&gt;src&lt;/em&gt; directory. Create a &lt;code&gt;users.ts&lt;/code&gt; file in the &lt;em&gt;dataSources&lt;/em&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MongoDataSource } from 'apollo-datasource-mongodb';
import { ObjectId } from 'mongodb';
import { UserDocument, Context } from '../types';

export default class Users extends MongoDataSource&amp;lt;UserDocument, Context&amp;gt; {

  getUsers() {
    return this.collection.find().toArray();
  }

  getUser(userId: ObjectId) {
    return this.collection.findOne({_id: new ObjectId(userId)});
  }

  addUser(username: string, password: string, email: string) {
    return this.collection.insertMany([{username, password, email}]);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;index.ts&lt;/code&gt; file in the directory &lt;em&gt;src&lt;/em&gt; and make it look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose, { ObjectId } from 'mongoose';
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { GraphQLError } from 'graphql';
import express from 'express';
import http from 'http';
import cors from 'cors';
import { User as UserModel } from './models/user.js';
import Users from './dataSources/users.js';
import pkg from 'body-parser';
import { UserDocument } from './types.js';
const { json } = pkg;

await mongoose.connect('mongodb://127.0.0.1:27017/ragnemt');

const app = express();
// Our httpServer handles incoming requests to our Express app.
// Below, we tell Apollo Server to "drain" this httpServer,
// enabling our servers to shut down gracefully.
const httpServer = http.createServer(app);

const typeDefs = `#graphql
  type User {
    _id: ID!
    username: String
    password: String
    email: String
  }
  type Query {
    users: [User]
    user(_id: ID!): User
  }
  type Mutation {
    addUser(username: String, password: String, email: String): User
  }
`;

const resolvers = {
  Query: {
    users: (_parent: any, _args: any, { dataSourses }) =&amp;gt; {
      return  dataSourses.users.getUsers();
    },
    user: (_parent: any, { _id }, { dataSourses }) =&amp;gt; {
      return dataSourses.users.getUser(_id)
        .then((res: UserDocument) =&amp;gt; {
          if (!res) {
            throw new GraphQLError(
              `User with User Id ${_id} does not exist.`
            );
          }
          return res;
        });
    },
  },
  Mutation: {
    addUser: (_parent: any, { username, password, email }, { dataSourses }) =&amp;gt; {
      return dataSourses.users.addUser(username, password, email)
        .then((res: { insertedIds: ObjectId[]; }) =&amp;gt; ({ _id: res.insertedIds[0], username, password, email }))
    }
  }
}

interface MyContext {
  dataSources?: {
    users: Users;
  };
}

const server = new ApolloServer&amp;lt;MyContext&amp;gt;({
  typeDefs,
  resolvers,
  plugins: [
    // Proper shutdown for the HTTP server.
    ApolloServerPluginDrainHttpServer({ httpServer }),
  ],
});
await server.start();

app.use(
  cors&amp;lt;cors.CorsRequest&amp;gt;(),
  json(),
  expressMiddleware(server, {
    context: async ({ req }) =&amp;gt; ({
      token: req.headers.token,
      dataSourses: {
        users: new Users(await UserModel.createCollection())
      }
    }),
  }),
);

app.listen({ port: 4000 }, () =&amp;gt; console.log(`🚀 Server ready at http://localhost:4000`))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The structure of the server side of the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frb1e8l0cgulwqchgvo4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frb1e8l0cgulwqchgvo4d.png" alt="Image description" width="306" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the following changes to package.json file:&lt;br&gt;
&lt;code&gt;"type": "module",&lt;br&gt;
  "scripts": {&lt;br&gt;
    "build": "tsc",&lt;br&gt;
    "start": "nodemon --exec ts-node-esm ./src/index.ts"&lt;br&gt;
  },&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
The configuration of the package.json file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "nodemon --exec ts-node-esm ./src/index.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@apollo/server": "^4.7.0",
    "@types/body-parser": "^1.19.2",
    "@types/cors": "^2.8.13",
    "apollo-datasource-mongodb": "^0.5.4",
    "body-parser": "^1.20.2",
    "express": "^4.18.2",
    "graphql": "^16.6.0",
    "mongoose": "^7.1.0"
  },
  "devDependencies": {
    "@types/node": "^18.16.2",
    "nodemon": "^2.0.22",
    "ts-node": "^10.9.1",
    "typescript": "^5.0.4"
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install nodemon and ts-node:&lt;br&gt;
&lt;code&gt;npm i --save-dev nodemon ts-node&lt;/code&gt;&lt;br&gt;
Run &lt;code&gt;npm start&lt;/code&gt;:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fio31d240o5gex4j5jwhf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fio31d240o5gex4j5jwhf.png" alt="Image description" width="443" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The server side is working!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Client&lt;/strong&gt;&lt;br&gt;
Create a &lt;em&gt;client&lt;/em&gt; directory under the &lt;em&gt;ragnemt-app&lt;/em&gt; directory.&lt;br&gt;
Go to the &lt;em&gt;client&lt;/em&gt; directory. Start a new Create React App project with TypeScript:&lt;br&gt;
&lt;code&gt;npx create-react-app . --template typescript&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install Apollo Client and GraphQL:&lt;br&gt;
&lt;code&gt;npm i @apollo/client graphql&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Change index.tsx to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ReactDOM from 'react-dom/client';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import './index.css';
import App from './App';

const client = new ApolloClient({
  uri: 'http://localhost:4000/',
  cache: new InMemoryCache(),
});

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  &amp;lt;ApolloProvider client={client}&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/ApolloProvider&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change index.css to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}

td,
th {
    border: 1px solid rgb(190, 190, 190);
    padding: 10px;
}

th[scope='col'] {
  background-color: #696969;
  color: #fff;
}

th[scope='row'] {
  background-color: #d7d9f2;
}

td {
    text-align: center;
}

tr:nth-child(even) {
  background-color: #eee;
}

caption {
  padding: 10px;
  /* caption-side: bottom; */
}

table {
  border-collapse: collapse;
  border: 2px solid rgb(200, 200, 200);
  letter-spacing: 1px;
  font-family: sans-serif;
  font-size: 0.8rem;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change App.tsx to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import AddUser from './components/AddUser';
import GetUsers from './components/GetUsers';
import GetUser from './components/GetUser';
import './App.css';

const App = () =&amp;gt; {

  const OnChangeTab = (e: React.MouseEvent&amp;lt;HTMLButtonElement, MouseEvent&amp;gt;, activeTab: string) =&amp;gt; {
    const tabcontent = document.getElementsByClassName("tabcontent");
    for (let i = 0; i &amp;lt; tabcontent.length; i++) {
      tabcontent[i].setAttribute("style","display:none");
    }
    const tablinks = document.getElementsByClassName("tablinks");
    for (let i = 0; i &amp;lt; tablinks.length; i++) {
      tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    document.getElementById(activeTab)?.setAttribute("style","display:block");
    e.currentTarget.className += " active";
  }

  return (
    &amp;lt;&amp;gt;
      &amp;lt;div className="tab"&amp;gt;
        &amp;lt;button className="tablinks active" onClick={(e) =&amp;gt; OnChangeTab(e, 'Users')}&amp;gt;Users&amp;lt;/button&amp;gt;
        &amp;lt;button className="tablinks" onClick={(e) =&amp;gt; OnChangeTab(e, 'User')}&amp;gt;User&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div id="Users" className="tabcontent"&amp;gt;
        &amp;lt;h3&amp;gt;Users&amp;lt;/h3&amp;gt;
        &amp;lt;AddUser /&amp;gt;
        &amp;lt;GetUsers /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div id="User" className="tabcontent" style={{display: 'none'}}&amp;gt;
        &amp;lt;h3&amp;gt;User&amp;lt;/h3&amp;gt;
        &amp;lt;GetUser /&amp;gt;
      &amp;lt;/div&amp;gt;

    &amp;lt;/&amp;gt;
  )

}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change App.css to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Style the tab */
.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

/* Style the buttons inside the tab */
.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
  font-size: 17px;
}

/* Change background color of buttons on hover */
.tab button:hover {
  background-color: #ddd;
}

/* Create an active/current tablink class */
.tab button.active {
  background-color: #ccc;
}

/* Style the tab content */
.tabcontent {
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;em&gt;graphql&lt;/em&gt; directory under the &lt;em&gt;src&lt;/em&gt; directory.&lt;br&gt;
Create a &lt;code&gt;queries.ts&lt;/code&gt; file in the &lt;em&gt;graphql&lt;/em&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { gql } from "@apollo/client";

export const GET_USERS = gql`
query GetUsers {
  users {
    _id
    username
    password
    email
  }
}
`;

export const GET_USER = gql`
query getUser ($id: ID!) {
  user(_id: $id) {
    _id
    username
    email
    password
  }
}
`;

export const ADD_USER = gql`
mutation AddUser($username: String, $password: String, $email: String) {
  addUser(username: $username, password: $password, email: $email){
        username
        password
        email
  }
}
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;em&gt;components&lt;/em&gt; directory under the &lt;em&gt;src&lt;/em&gt; directory.&lt;br&gt;
Create a &lt;code&gt;AddUser.tsx&lt;/code&gt; file in the &lt;em&gt;components&lt;/em&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useMutation } from '@apollo/client';
import {GET_USERS, ADD_USER} from '../graphql/queries';

const AddUser = () =&amp;gt; {
    let inputName: HTMLInputElement | null;
    let inputPassword: HTMLInputElement | null;
    let inputEmail: HTMLInputElement | null;

    const [addUser, { loading, error, client }] = useMutation(ADD_USER);

    if (loading) return &amp;lt;p&amp;gt;'Submitting...'&amp;lt;/p&amp;gt;;

    return (
      &amp;lt;div&amp;gt;
        {error &amp;amp;&amp;amp; &amp;lt;p&amp;gt;`Submission error! ${error.message}`&amp;lt;/p&amp;gt;}
        &amp;lt;form
          onSubmit={e =&amp;gt; {
            e.preventDefault();
            addUser({
              variables: { username: inputName?.value, password: inputPassword?.value, email: inputEmail?.value },
              refetchQueries: [{ query: GET_USERS }],      
              onError: () =&amp;gt; client.refetchQueries({ include: [GET_USERS] })
            });
          }}
        &amp;gt;
          &amp;lt;input
            ref={node =&amp;gt; { inputName = node; }}
            placeholder='Name'
            required
          /&amp;gt;
          &amp;lt;input
            ref={node =&amp;gt; { inputPassword = node; }}
            placeholder='Password'
            required
          /&amp;gt;
          &amp;lt;input
            type='email'
            ref={node =&amp;gt; { inputEmail = node; }}
            placeholder='Email'
            required
          /&amp;gt;
          &amp;lt;button type="submit"&amp;gt;Add User&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }

  export default AddUser;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;GetUser.tsx&lt;/code&gt; file in the &lt;em&gt;components&lt;/em&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useLazyQuery } from '@apollo/client';
import { GET_USER } from '../graphql/queries';

const GetUser = () =&amp;gt; {
  let inputId: HTMLInputElement | null = null;
  const [getUser, { loading, error, data }] = useLazyQuery(GET_USER);

  if (loading) return &amp;lt;p&amp;gt;'Submitting...'&amp;lt;/p&amp;gt;;

  return (
    &amp;lt;div&amp;gt;
      {error &amp;amp;&amp;amp; &amp;lt;p&amp;gt;`Submission error! ${error.message}`&amp;lt;/p&amp;gt;}
      &amp;lt;form
        onSubmit={e =&amp;gt; {
          e.preventDefault();
          getUser({ variables: { id: inputId?.value } })
        }}
      &amp;gt;
        &amp;lt;input
          ref={node =&amp;gt; { inputId = node; }}
          placeholder='UserId'
          required
        /&amp;gt;
        &amp;lt;button type="submit"&amp;gt;Get User&amp;lt;/button&amp;gt;
        {data?.user &amp;amp;&amp;amp;
          &amp;lt;table style={{ minWidth: 300 }}&amp;gt;
            &amp;lt;caption&amp;gt;User&amp;lt;/caption&amp;gt;
            &amp;lt;tbody&amp;gt;
              &amp;lt;tr&amp;gt;
                &amp;lt;th scope="row"&amp;gt;User ID&amp;lt;/th&amp;gt;
                &amp;lt;td&amp;gt;{data?.user._id}&amp;lt;/td&amp;gt;
              &amp;lt;/tr&amp;gt;
              &amp;lt;tr&amp;gt;
                &amp;lt;th scope="row"&amp;gt;User name&amp;lt;/th&amp;gt;
                &amp;lt;td&amp;gt;{data?.user.username}&amp;lt;/td&amp;gt;
              &amp;lt;/tr&amp;gt;
              &amp;lt;tr&amp;gt;
                &amp;lt;th scope="row"&amp;gt;User email&amp;lt;/th&amp;gt;
                &amp;lt;td&amp;gt;{data?.user.email}&amp;lt;/td&amp;gt;
              &amp;lt;/tr&amp;gt;
            &amp;lt;/tbody&amp;gt;
          &amp;lt;/table&amp;gt;
        }
        &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;


      &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default GetUser;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;GetUsers.tsx&lt;/code&gt; file in the &lt;em&gt;components&lt;/em&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useQuery } from '@apollo/client';
import { GET_USERS } from '../graphql/queries';
const GetUsers = () =&amp;gt; {
  const { data, loading, error } = useQuery(GET_USERS);

  if (loading) return &amp;lt;p&amp;gt;...Loading&amp;lt;/p&amp;gt;;
  if (error) return &amp;lt;p&amp;gt;Error: {error.message}&amp;lt;/p&amp;gt;;

  return (
    &amp;lt;table&amp;gt;
      &amp;lt;caption&amp;gt;Users&amp;lt;/caption&amp;gt;
      &amp;lt;thead&amp;gt;
        &amp;lt;tr&amp;gt;
          &amp;lt;th scope="col"&amp;gt;User ID&amp;lt;/th&amp;gt;
          &amp;lt;th scope="col"&amp;gt;User name&amp;lt;/th&amp;gt;
          &amp;lt;th scope="col"&amp;gt;User email&amp;lt;/th&amp;gt;
        &amp;lt;/tr&amp;gt;
      &amp;lt;/thead&amp;gt;
      &amp;lt;tbody&amp;gt;
        {data.users.map(({ _id, username, email }: { _id: string, username: string, email: string }) =&amp;gt; (
          &amp;lt;tr key={_id}&amp;gt;
            &amp;lt;td&amp;gt;{_id}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{username}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{email}&amp;lt;/td&amp;gt;
          &amp;lt;/tr&amp;gt;
        ))}
      &amp;lt;/tbody&amp;gt;
    &amp;lt;/table&amp;gt;
  )
}

export default GetUsers;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The structure of the client side of the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1o1xqz6zjzduhm3cq9f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1o1xqz6zjzduhm3cq9f.png" alt="Image description" width="306" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The configuration of the package.json file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@apollo/client": "^3.7.13",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.25",
    "@types/react": "^18.2.0",
    "@types/react-dom": "^18.2.1",
    "graphql": "^16.6.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.5",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      "&amp;gt;0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;npm start&lt;/code&gt;. We can now view client in the browser: &lt;code&gt;http://localhost:3000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9ofp4csx07ttrc070q7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9ofp4csx07ttrc070q7.png" alt="Image description" width="664" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter &lt;code&gt;Good Man&lt;/code&gt; in the Name field. Enter &lt;code&gt;123&lt;/code&gt; in the Password field. Enter &lt;code&gt;good_man@gm.net&lt;/code&gt; in the Email field. Click the button &lt;code&gt;Add User&lt;/code&gt;. The information will be displayed in the users table:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvsc9wheqfvinwo3xtzwp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvsc9wheqfvinwo3xtzwp.png" alt="Image description" width="686" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy &lt;code&gt;User ID&lt;/code&gt;. Go to tab &lt;code&gt;User&lt;/code&gt;. Paste &lt;code&gt;User ID&lt;/code&gt; in the UserId field. Click the button &lt;code&gt;Get User&lt;/code&gt;. User information will be displayed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fab9obmj9bio6w1k21rf7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fab9obmj9bio6w1k21rf7.png" alt="Image description" width="487" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything is working!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>node</category>
      <category>mongodb</category>
      <category>react</category>
    </item>
  </channel>
</rss>
