My own realtime chat with react, graphql and postgresql [part 7 - React Login]
Tags: react, graphql, html
Published: 2020-10-28 20:23:13

In this part we'll be seeing how to start the apollo client in react, use mutations and signin our first user from the web.

[Previously](https://dev.to/dalejan/my-own-realtime-chat-with-react-graphql-and-postgresql-part-6-react-setup-36pk) we saw the first steps in the project structure and the routing system, but we didn't create the containers that renders those url paths, so let's do it!

But first we have to configure our apollo-client in order to use apollo in react. For this let's install some packages: `npm i @apollo/client apollo-utilities graphql apollo-link-ws subscriptions-transport-ws graphql-tag`.

*./graphql/client.js*
```javascript
import { ApolloClient, HttpLink, InMemoryCache, split } from "@apollo/client";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";

const server_url = process.env.SERVER_URL;

const httpLink = new HttpLink({
  uri: "http://server_url",
});

// Create a WebSocket link:
const wsLink = new WebSocketLink({
  uri: `ws://server_url`,
  options: {
    reconnect: true,
  },
});

const link = split(
  // split based on operation type
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === "OperationDefinition" &&
      definition.operation === "subscription"
    );
  },
  wsLink,
  httpLink
);

export const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: link,
});

```

There is a few important things happening here.
1. `ApolloClient` will allow us to compose a client object to use it as a provider so our app can access this api from any component under the main component node we define.
2. The `server_url` constant is the path that we got from deploy our server, if we are running this locally it would be something like `localhost:8080/graphql`.
3. The `HttpLink` and the `WebSocketLink` are link creators, we'll use those links to comunicate with the sockets and http api we defined in our backend.
4.The `split` operator let us redirect the queries, mutations and subscriptions to the specific endpoints they correspond to.

Now we can provide this client to all our app so we can excecute the graphql operations wherever we like.

*./App.jsx*
```javascript
import { ApolloProvider } from "@apollo/client";
import React from "react";
import { HashRouter } from "react-router-dom";
import AppRouter from "./AppRouter";
import { client } from "./graphql/client";
import appRoutes from "./routes/app.routes";

const App = () => {
  return (
    <div className="App">
      <ApolloProvider client={client}>
        <HashRouter basename="/">
          <AppRouter routes={appRoutes} />
        </HashRouter>
      </ApolloProvider>
    </div>
  );
};

export default App;

```

Now we actually can connect to the backend, but first we have to define what we want to say to it, or what we want it to answer us.

To do this let's define our first operation, the signin mutation.

*./graphql/mutations/signIn.js*

```javascript
import gql from "graphql-tag";

export default gql`
  mutation signInMutation($usr: String, $password: String) {
    signInUser(usr: $usr, password: $password) {
      usr
      name
      type
      token
    }
  }
`;

```

`gql` is basically a graphql interpreter that reads a string and translate it into graphql language. You may have notice that this string is exactlly the same we tested in the playground, *shout-out to the playground!*

Now we can consume this specific endpoint. 

#####Let's login.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l6hx1fokuf9z8nnn0e37.gif)

*./containers/Login/Login.jsx*

```javascript
import { useMutation } from "@apollo/client";
import React, { useEffect } from "react";
import Signin from "../../components/Signin/Signin";
import SIGNIN_USER from "../../graphql/mutations/signIn";

const Login = () => {
  const [signInUser, { data, error, loading }] = useMutation(SIGNIN_USER);

  const onSubmitSignin = (fields) => {
    signInUser({
      variables: { usr: fields.username, password: fields.password },
    });
  };

  useEffect(() => {
    if (!loading) {
      console.log(data);
      if (data?.signInUser.usr) {
        console.log("Should let me in");
      } else {
        console.log("You shall not pass");
      }
    }
  }, [data, loading]);

  return (
    <div>
      <Signin onSubmit={onSubmitSignin}></Signin>
    </div>
  );
};

export default Login;
```

As always, let's check this piece of code.

1. The `useMutation` hook allow us to execute the `SIGNIN_USER` mutation as a function `signInUser`, also it let us check the data, if an error occur and whereas our petition is loading.
2. The `Signin` component is just a form that resolve the username and the password, so it's submit function fires the `signInUser` mutation with those params.
3. Using the `useEffect` hook we can check for data and loading states to change.

To check if everything is ok you could create a new user in the playground, and come back to the app to try those credentials. The console should print `Should let me in`.

In the next part we'll use the routing system we created so we can navigate to the chatroom container. As an exercise you should try to build the signup flow (*hint: it's pretty similar*).