Building a Web App with ReactJS and Appwrite
Tags: react, appwrite, webdev, tutorial
Published: 2021-10-28 10:09:01

In this post, I will be showing how we can build a web app with ReactJS and Appwrite. Let's start by first describing what exactly are we going to build. 

#### Web App Description
We will be building a travel journal in which you will be able to store all your travel experiences at one place, we will also be implementing Google Authentication in our web app thus making sure all the content we store is secure.

#### Getting Started with Appwrite
1. **Appwrite is a self-hosted solution that provides developers with a set of easy-to-use and integrate REST APIs to manage their core backend needs. Visit https://appwrite.io/ to know more about Appwrite.**
2. Follow the [installation guide](https://appwrite.io/docs/installation) to set up Appwrite on your local machine.
3. Once you installed appwrite,go to your appwrite console to start with a new project.
4. Once created a new project, navigate to **Users** option and enable Google Auth option in settings.
5. Follow the documentation given there to set your *APPID* and *APPSECRETKEY* to enable Google Auth.

#### Creating a New React Project
1. Do ```npx create-react-app appname``` to create a new react app.
2. Do ```npm install appwrite``` to add appwrite to your project.

#### Setting Up Authentication in our app.
1. Create a new file appwrite.js, this is where we will initialize our appwrite SDK as given below. You can navigate to your project settings in appwrite console to get your Project UID and Endpoint.
2. Now, before moving forward, make sure you have enabled Google Auth in our appwrite console and initialized appwrite SDK in your project. 
3. We will then define a function **loginWithGoogle** in our appwrite.js file like this -
```javascript
import { Appwrite } from "appwrite";

var appwrite = new Appwrite();
appwrite
    .setEndpoint('') // Set your endpoint
    .setProject('') // Your Appwrite Project UID
    ;
export const api = {
    loginWithGoogle: async () => {
        try {
            await appwrite.account.createOAuth2Session('google', 'http://localhost:3000/dashboard/', 'http://localhost:3000/');
        } catch (error) {
            throw error;
        }
    },
}
```
Here, the two endpoints refer to the site endpoints that the user will be redirected in case of first success and second failure.
4. Once defined, we will call this function on our home page in this manner - 
```javascript
import { api } from '../api/appwrite'
function Home() {
    const loginwithGoogle = async () => {
        try {
            await api.loginWithGoogle();
        } catch (error) {
            console.log(error.message);
        }
    }
}
```
```javascript
 <button onClick={loginwithGoogle}>Login with Google</button>                       
```
5. Now, if the user logs in successfully, they will be redirected to the Dashboard page where all their posts will be visible.
6. Before moving forward, let's add the logout functionality, for which we will be defining a userLogout function in appwrite.js like this - 
```javascript
userLogout: async () => {
        let promise = appwrite.account.deleteSession('current');
        promise.then(function (response) {
            console.log(response); // Success
        }, function (error) {
            console.log(error); // Failure
        });
    },
```
and we be calling this function in Dashboard.js like this  - 

```javascript
import { api } from '../api/appwrite'

function Dashboard(){
const logoutUser = async () => {
        try {
            await api.userLogout();
        } catch (error) {
            console.log(error.message);
        }
    }
}
```
```javascript
<button onClick={logoutUser}>Logout</button>
```

#### Storing and Retrieving Data from Appwrite Database
1. Now, since we have successfully setup Google authentication in our app. Let's see how we can store our data in Appwrite Database.
2. We will start with creating a new **Collection** called **Posts** in our appwrite console and setup the following rules and permissions for our project.

#### Collection rules

We have defined three fields date, location and experience to store the date, location and experiences for various trips. All 3 fields are required here.

| Label         | Key           | Rule  |          |
| ------------- |:-------------:| -----:|---------:| 
| date          | date          | Text  | Required |
| location      | location      | Text  | Required |
| experience    | experience    | Text  | Required |
 

#### Permissions - 
Refer https://appwrite.io/docs/permissions to know more about Permissions. Here <code>role:member</code> implies that anyone who is logged in has read and write access to collection.
 1. Read access - <code>role:member</code>
 2. Write access - <code>role:member</code>

#### Creating Document 

1. Once we have completed our Collection setup, let's create our first document by defining this function in appwrite.js. Here, since we have not defined any permissions in createDocument function by default person creating the document only has the read and write permissions.
```javascript
postData: async (date, location, content) => {
let promise = appwrite.database.createDocument('CollectionId', { "date": date, "location": location, "experience": content });

promise.then(function (response) {
            console.log(response); // Success
        }, function (error) {
            console.log(error); // Failure
        });
    },
```
2. Now, we will be calling this function in Dashboard.js, where we have defined input fields to add data in this way - 
```javascript
 const [date, setdate] = useState('2021/10/20')
 const [location, setlocation] = useState('')
 const [content, setcontent] = useState('')

 const handleSubmit = async () => {
        try {
            user = await api.getCurrentUser()
            await api.postData(date, location, content);
            alert("Added successfully")
        } catch (error) {
            console.log(error.message);
        }
    }
```

```javascript
<input placeholder="Enter date" type="date" value={date} onChange={(e) => setdate(e.target.value)}></input>

<input placeholder="Enter location" type="text" value={location} onChange={(e) => setlocation(e.target.value)}></input>

<textarea placeholder="Enter experience" type="text" value={content} onChange={(e) => setcontent(e.target.value)}></textarea>

<button onClick={handleSubmit}>Add</button>                                                        
```

#### Getting Document

Since now we are able to successfully store data, let's see how we can get that data and display on our Dashboard page.

2. For this, we will be defining this function in appwrite.js -

```javascript
 getData: async () => {
 let promise = appwrite.database.listDocuments('collectionId');

        return promise.then(function (response) {
            //response.documents is a array
            return response.documents
        }, function (error) {
            console.log(error); // Failure
        });
    },
```
3. Now, let's call this function in Dashboard.js inorder to display our data.

```javascript
const [postItems, setPostItems] = useState([])

useEffect(() => {
        const getPostData = async () => {
            try {
                await api.getData().then((res) => {
                    console.log(res)
                    const stateData = []; // make a temporary const to store your state to be set
                    res.forEach((doc) => {
                        stateData.push({
                            "location": doc.location,
                            "date": doc.date,
                            "text": doc.experience
                        });
                    });
                    // finally set your state here
                    setPostItems([...stateData]);
                })
            } catch (error) {
                console.log(error.message);
            }
        }
        getPostData();
        console.log(postItems)
    }, [])
```
```javascript
 {postItems.map((element) => {
      return (
           <p>{element.date}</p>
           <p>{element.location}</p>
           <p>{element.text}</p>
            )
  })}
```

And, we are done with our app 🎉🎉. We have successfully implemented Google Authentication and connected our app with Appwrite Database to store and get our data easily.

<img width="100%" style="width:100%" src="https://media3.giphy.com/media/aQYR1p8saOQla/giphy.gif?cid=ecf05e47inldatd22c8m3f1elz4xirzljtstr8i3yg4pybg1&rid=giphy.gif&ct=g">

[Github Repo](https://github.com/drishtipeshwani/Tourpal) - Feel free to refer to this github repo for source code for this app.