How to juggle in between two containers (ReactJS)
Tags: react, javascript, beginners
Published: 2023-02-21 17:50:17

Hi all,

In phase 2 of my coding bootcamp we were learning React (framework on top of JavaScript I had wanted to do something a little bit different. Also, at this point in time we didn't learn how to build the backend yet. I had to generate a mock data in JSON format and then host that in order for my front end to fetch data to display from. 

This project was to showcase Bob Ross's paintings. My initial thoughts was that I will have two containers. One container showing all of Bob Ross's paintings (container A) and the other would be where you can favorite them (container B). 

However, I want to copy (THEN delete) the information of the container A and send it to container B. And, vice versa. 

First, what I had to do was to fetch the data for both container A and B. The initial data for container B was to be empty (because no favorites yet). 

```javascript
 useEffect(() => { // fetch paintings
  const fetchData = async () => {
    try {
      const resp = await fetch("http://localhost:3000/paintings")
      const paintings = await resp.json()
      setPaintings(paintings)
    } catch (error) {
      alert(error)
    }
   }
   fetchData()
}, [])
```

I also did this with the other container (B). Then, I want to mapped all the data into each container's cards. So, then I created all the respective container A/B cards for them to have SOC. 

```javascript
const mappedPaintings = paintings.map(painting => (<PaintingCard key={painting.id} /> 
)
)
```
paintings = refers to the inherited useState value from its parental component through props
PaintingCard (component) = the child component of the container A

Note: I also passed down a couple more props down into this child container as well but to not clog the code and make it look confusing I will omit them.


Thereafter, building a structure for my JSX.

```javascript
return(
<div>
{mappedPaintings}
</div>
)
```

Then, inside the PaintingCard component I passed down a couple useState set functions. I won't note it here but it'll be assumed. 

So again, building a simple JSX structure. 

```javascript
return(
<div>

<div>
{painting.title}
</div>
<img src={painting.img_src} alt={painting.title} />
<button onClick={handleDelete}>Add to My Gallery</button>

</div>
)
```
So now our mapped Data should show us the painting title and image. I also build a button to handle delete... that's kinda misleading since it'll fire a POST request before deleting itself. For simplicity sake I chose that name so please bear with it.

As for the handleDelete callback function, 

```javascript
const { id } = useParams()
const finalPainting = !painting ? myPainting : painting
const handleDelete = () => {
const paintingToAdd = {...finalPainting, id:null }
        
        fetch("http://localhost:3000/gallery",{
            method: "POST",
            headers:{
                "Content-Type": "application/json"
            },
            body: JSON.stringify(paintingToAdd)
        })
        .then(response => response.json())
        .then(paintingObj => setMyPaintings(currentVal => [paintingObj, ...currentVal]))
        .catch(error => alert(error))

        fetch(`http://localhost:3000/paintings/${painting.id}`,
            {
                method: "DELETE"
            })
        setPaintings(currentPaintings => currentPaintings.filter(element => element.id !== painting.id))
    }
```
A lot to take in, I know. Even worse when you're trying to build this. Remember that I need to have another one going vice versa. I will walkthrough each part.

```javascript
const finalPainting = !painting ? myPainting : painting
```
This variable determines which painting we are choosing

```javascript
const paintingToAdd = {...finalPainting, id:null }
```
This spreads (iterates/copy all of its object) the finalPainting variable and sets the id of each object to null. ***

```javascript
 fetch("http://localhost:3000/gallery",{
            method: "POST",
            headers:{
                "Content-Type": "application/json"
            },
            body: JSON.stringify(paintingToAdd)
        })
        .then(response => response.json())
        .then(paintingObj => setMyPaintings(currentVal => [paintingObj, ...currentVal]))
        .catch(error => alert(error))
```
This fires a POST fetch to mock database (and stringify the object we are sending) and renders/set the state for the container B, and to alert us if it catches any error.

```javascript
 fetch(`http://localhost:3000/paintings/${painting.id}`,
            {
                method: "DELETE"
            })
        setPaintings(currentPaintings => currentPaintings.filter(element => element.id !== painting.id))
```
This fires a DELETE fetch to mock database. I made use of useParams to target the right painting by interpolating the id into the path. Then, it renders/set the state for the container A by getting any painting that DOESN'T have the painting id that we JUST deleted. 

***I had to set id to null because if you don't and you send back the painting with the same id the database will not like that because id is the unique identifier... meaning there can be only one of that value. So, setting all the id to null addresses this problem.

We have successfully move content from container A to B while erasing the original content from container A.

Now, I just did the same but going from container B to A. 
There you have it, a 'juggling container system' (I coined it).

Thanks for reading!