# AWS Amplify + React Native - Building A Blog App | Part 3

Welcome to the third and final part of this series. If you've come here directly, it is advisable to read the first two parts before you continue.
 
[**Part 1**](https://techblog.geekyants.com/aws-amplify-react-native-building-a-blog-app-or-part-1) 

[**Part 2**](https://techblog.geekyants.com/aws-amplify-react-native-building-a-blog-app-or-part-2)  

# Table Of Contents

- [Fetching Posts](#fetching-posts)
- [Creating A New Post](#creating-a-new-post)
- [Editing Posts](#editing-posts)
- [Deleting Posts](#deleting-posts)
- [Conclusion](#conclusion)


Now that we have handled the Navigation for the app using Cognito, we should move on the final phase, which is the implementation of making and receiving requests to fetch and show data on the app. Since the app that we’re making is a blog app, it should be able to display existing blog posts, create new posts and obtain edit/delete functionalities, all within the app.

We tried doing this before from the dashboard by making GraphQL calls in the first part. We’re essentially doing the same thing, but straight from the app.

Let’s first find the place where our first post was saved. To do that:

Go to your **AWS console** -> Click on **Services** -> Click on **DynamoDB** on the left panel (our default DB) -> Click on **Tables**.

![image2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1608205832620/kbbNjxlEk.png)

You should see a Table already created (if you’ve been following along). Access the Table and click on Items. There, you will be able to see the post that we created in the first part, just sitting there casually. We created this post using a test account. 

Let’s create some with a real account.

## Fetching Posts

First, login with the main account in the app. Now in the code, make your way to `HomeScreen.js`. There, you’ll see a constant with the name `data`, which is an array of dummy objects in the form of the schema that we’ve defined. We’re going to replace this data with the actual data stored in DynamoDB.

Import these statements into the `HomeScreen.js` file:

```
import { API, graphqlOperation } from 'aws-amplify'
```
```
import * as queries from ‘./../graphql/queries’
```
The above line retrieves all queries from the DB, which we can filter at a later stage. To fetch posts in the app, add the following code:

```
async function fetchPosts() {
    try {
      const { data } = await API.graphql(graphqlOperation(queries.listPosts));
      setData(data.listPosts.items);
    } catch (err) {
      console.log(err, 'error fetching todos');
    }
  }

  useFocusEffect(
    useCallback(() => {
      fetchPosts();
    }, [])
  );
```
This component, whenever mounted, will fetch the posts by making a query to list all posts using `queries.listPosts`.

We have also wired this data to our UI. We need to create a new State variable to store the data that we’ll be getting. Let’s create a variable and call it `data`. Initially, it will be an empty array.

` const [data, setData] = useState([]);`

...but when we get the data, we will display the data using:

```
const { data } = await API.graphql(graphqlOperation(queries.listPosts));
      setData(data.listPosts.items);
```
 > Remember to replace the hard coded `DATA` state with this current state in the UI.

## Creating A New Post

We’re going to try the same approach used above to be able add new posts through the app. Adding a new post would essentially be a mutation.

Navigate to `CreateScreen.js`and import the same GraphQL query operations statements from above.

Then, add the following lines of code:

```
import * as mutations from '../graphql/mutations';
```
```
const handleSubmit = async () => {
    setLoading(true);
          try {
        const { title, description } = formState;
        await API.graphql(
          graphqlOperation(mutations.createPost, {
            input: { title, description, createdBy: user.email }
          })
        );
        setFormState({});
        setLoading(false);
      } catch (err) {
        setLoading(false);
        console.log('error creating post:', err);
      }
    
  };
```
We are importing all mutations from GraphQL. `handleSubmit` is an `async` function that will take input fields and return them as `title`, `description` and specify the `owner` of the post.
As far as the ownership of the user is concerned, Amplify stores all attributes like Email, User Pool ID, JWT tokens etc. for every user and uses this data to identify the current user. We don’t have to use this data for our operations at all. We’ll just store the `username` and `email` in the context that we’re using.

Navigate to the `AppNavigation.js` file and find `AppNavigation()` and add `setUser` as a constant and add the following line:

```
setUser({ username: user.username, email: user.attributes.email });
```

Also, add the following line in `AuthContext.js`:

```
 const [user, setUser] = useState({});
```

To consume this data, first add `useContext` in the import statement and then add the following line of code:

```
import { AuthContext } from '../AuthContext';
```
Display the user name with a welcome message by returning `user.username`.

![image1.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1608205878523/HM4D5K-SF.png)

> To handle the situation where a different user signs in, navigate to `LoginScreen.js`, add `setUser` in the context and define setUser() in the Sign In module.

FInally, to set the ownership of each added post, import the following lines in `CreateScreen.js`:

```
 const { user } = useContext(AuthContext);
```
```
import * as mutations from '../graphql/mutations';


```
Then add an `owner:user.email` field in `graphqlOperation()`.

Note that at this point of time, I updated the existing schema to remove some mistakes and add a new operation. I replaced the `owner` field to `createdBy` and added an `update` operation.

At this point, you should be able to create new posts and check them in the DynamoDB table.

## Editing Posts

Let’s implement the editing and deleting function for all the posts on the app. While writing these functionalities, it is very important to remember that these functionalities should only be available to the owners of the post and no-one else.

The first thing to do is import an icon in the UI that represents the edit option. Then, navigate to `HomeScreen.js` and add the following line:

```
editable={user.email === item.createdBy}
```
This implements the condition that the edit option is only available on a post when its owner is accessing it. The next is to make sure that when the edit button is tapped, the fields should be prefilled with the existing data, that can be edited and should not be empty.

In `HomeScreen.js`, import `routes`, add the `navigation` & `id` prop in `const Item = ()` and add the following line to the `<TouchableOpacity>` for the `edited` function:

```
  <TouchableOpacity
            onPress={() => navigation.navigate(routes.Create, { id })}
            style={[t.pX2]}
          >
            <AntDesign name="edit" size={20} color={color.gray900} />
          </TouchableOpacity>
        )}
```
Also pass `navigation` to the `Item` component as a prop.

This will navigate the screen to the edit screen. To populate it with existing data, check the `route` parameter in `CreateScreen.js`, get the id of the post and copy the following code in `CreateScreen.js`:
```
import * as queries from '../graphql/queries';
```
```
 const { id } = route?.params || {};
```

```
 useEffect(() => {
    getPostById();
  }, []);

  const getPostById = async () => {
    try {
      const { data } = await API.graphql(
        graphqlOperation(queries.getPost, {
          id
        })
      );
      setFormState(data.getPost);
    } catch (err) {
      console.log('error creating post:', err);
    }
  };
```
Post this, all you need to do is make an update request under `handleSubmit`:

```
const handleSubmit = async () => {
    setLoading(true);
    if (id) {
      try {
        const { title, description } = formState;
        await API.graphql(
          graphqlOperation(mutations.updatePost, {
            input: { id, title, description }
          })
        );
        setFormState({});
        setLoading(false);
      } catch (err) {
        setLoading(false);
        console.log('error creating post:', err);
      }
    } else {
      try {
        const { title, description } = formState;
        await API.graphql(
          graphqlOperation(mutations.createPost, {
            input: { title, description, createdBy: user.email }
          })
        );
        setFormState({});
        setLoading(false);
      } catch (err) {
        setLoading(false);
        console.log('error creating post:', err);
      }
    }
  };
```
This will make the posts fully editable and update the changes in the posts. Of course, with the condition we implemented in the beginning, these changes can only be made by the owner of the posts.

## Deleting Posts

Deleting posts is pretty much the same as editing posts. A prop named `onDeletePost` exists in the code already. So, you can just call it:

```
const handleDelete = async () => {
    try {
      await API.graphql(
        graphqlOperation(mutations.deletePost, {
          input: { id }
        })
      );
      setFormState({});
    } catch (error) {
      console.log(error, 'error');
    }
  };

  const headerProps = {
    navigation,
    title: id ? 'Edit Post' : 'Create Post',
    ...(id && { onDeletePost: handleDelete })
  };
```
Put the call in a `try-catch` blog where we will pass the `id` of the post that needs to be deleted. 
That’s it! You’ll be able to delete the post through the account of the user who own them.


## Conclusion

It has been quite a journey but I’m glad that you stuck around till the end. At this stage, we’ve successfully implemented navigation, authentication and the basic functionalities of a blog app using AWS Amplify and its robust features. There is still a lot to explore and experiment with, so you’re more than welcome to do that and share your experiences here in the comments section. 

Thank you so much for reading. See you around!

This experiment has been carried out by ** [Sankhadeep Roy](https://twitter.com/sankhadeep_roy) **, Engineering Manager and AWS Enthusiast @[GeekyAnts](@geekyants) and documented by ** [Digvijay Wanchoo](https://twitter.com/digvijaywanchoo) **, A. Manager, Marketing & Communications @[GeekyAnts](@geekyants)
