React Using APIs: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 178: Line 178:
</syntaxhighlight>
</syntaxhighlight>
==Refactoring Thunk==
==Refactoring Thunk==
===Create the GET function===
Let make the GET a function.
Let make the GET a function.
<syntaxhighlight lang="js">  
<syntaxhighlight lang="js">  
Line 193: Line 194:
}
}
</syntaxhighlight>
</syntaxhighlight>
===Wrap the CRUD Functions===
Now we create function for each CRUD operation and we wrap it in a function that returns the cart and accepts dispatch and getState as the arguments. Here is ADD.
Now we create function for each CRUD operation and we wrap it in a function that returns the cart and accepts dispatch and getState as the arguments. Here is ADD.
<syntaxhighlight lang="js">  
<syntaxhighlight lang="js">  
Line 213: Line 215:
}
}
</syntaxhighlight>
</syntaxhighlight>
===Change Reducer Accept Generic CRUD Functions===
Within the original reducer we now have this becase the "refresh" functions passes the action to the refresh function which we will see in a moment.
Within the original reducer we now have this becase the "refresh" functions passes the action to the refresh function which we will see in a moment.
<syntaxhighlight lang="js">  
<syntaxhighlight lang="js">  
Line 233: Line 236:
export default CartReducer;
export default CartReducer;
</syntaxhighlight>
</syntaxhighlight>
===Implement new calls to helper functions===
Using the this we can create an instance of dispatch and pass the addCart function.
Using the this we can create an instance of dispatch and pass the addCart function.
<syntaxhighlight lang="js">  
<syntaxhighlight lang="js">  
Line 240: Line 244:
<button> type="button" ... onClick={() => dispatch(addCart()event.id)}...</button>
<button> type="button" ... onClick={() => dispatch(addCart()event.id)}...</button>
</syntaxhighlight>
</syntaxhighlight>
===Change UI from Promises Object===
We now return an object and now a promise so.
<syntaxhighlight lang="js">
        const state = CartStore.getState();
        if (state) {
            state.then((state) = {
                const cart = state.cart;
                const totalAmount = state.cart.reduce((p, n) => p + n.quantity * n.price, 0);
                setCart(cart);
                setTotalAmount(totalAmount);
            })
        }
    };
</syntaxhighlight>
Becomes
<syntaxhighlight lang="js">
        const state = CartStore.getState();
        if (state) {
            const cart = state.cart;
            const totalAmount = state.cart.reduce((p, n) => p + n.quantity * n.price, 0);
            setCart(cart);
            setTotalAmount(totalAmount);
        }
    };
</syntaxhighlight>
Using the Thunk

Revision as of 11:38, 23 June 2021

Introduction

This page is for how to use APIs with React.

When to call APIs

When using API here is where you should call the APIs

API for calling APIs

Options

There were 4 options offered.

  • Fetch API (Newish but OK)
  • Axios (Believe it is popular and have used)
  • JQuery (Never used)
  • XMLHttpRequest (old and liked - no surprise there)

Using Fetch

Here are the to ways to use fetch.

fetch("/path/to/API")
    .then(response => response.json())
    .then(data => {/* */})

const response = await fetch("/path/to/API");
const data = await response.json();

fetch("/path/to/API", {
    method: "POST",
    body: JSON.stringify(data),
    headers: { 'Content-Type': 'application/json'}
})

So within React this would look like this

const [events, setEvents] = useState([])

useEffect(() => {
    fetch("/path/to/API")
    .then(response => response.json())
    .then(data => {
        setEvents(data)
    })
}, [])

Example Reducer

Here is an example of using a reducer with an API

import UuidStore from "./UuidStore";

const CartReducer = async (state = { cart: [] }, action) => {
    let cart = state.cart;
    let response;

    switch (action.type) {
        case "add": 
            await fetch(
                "http://localhost:3333/cart",
                {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                        "X-SESSION-TOKEN": UuidStore.value
                    },
                    body: JSON.stringify({
                        id: action.payload.id
                    })
                }
            );
            response = await fetch(
                "http://localhost:3333/cart",
                {
                    method: "GET",
                    headers: {
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                }
            );

            cart = await response.json();
            return {
                ...state,
                cart: cart
            };
 
        case "update":
            if (action.payload.quantity === 0) {
                await fetch(
                    "http://localhost:3333/cart", {
                        method: "DELETE",
                        headers: { 
                            "Content-Type": "application/json",
                            "X-SESSION-TOKEN": UuidStore.value
                        },
                        body: JSON.stringify({
                            id: action.payload.event_id
                        })
                    });
            } else {
                await fetch(
                    "http://localhost:3333/cart", {
                        method: "PATCH",
                        headers: { 
                            "Content-Type": "application/json",
                            "X-SESSION-TOKEN": UuidStore.value
                        },
                        body: JSON.stringify({
                            id: action.payload.event_id,
                            quantity: action.payload.quantity
                        })
                    });    
            }
            response = await fetch(
                "http://localhost:3333/cart", {
                    method: "GET",
                    headers: { 
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                });
                
            cart = await response.json();
            return {
                ...state,
                cart: cart
            };
        case "delete":
            await fetch(
                "http://localhost:3333/cart", {
                    method: "DELETE",
                    headers: { 
                        "Content-Type": "application/json",
                        "X-SESSION-TOKEN": UuidStore.value
                    },
                    body: JSON.stringify({
                        id: action.payload.event_id
                    })
                });
            response = await fetch(
                "http://localhost:3333/cart", {
                    method: "GET",
                    headers: { 
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                });
                
            cart = await response.json();
            return {
                ...state,
                cart: cart
            };
        case "clear":
            await fetch(
                "http://localhost:3333/cart", {
                    method: "DELETE",
                    headers: { 
                        "Content-Type": "application/json",
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                });
            response = await fetch(
                "http://localhost:3333/cart", {
                    method: "GET",
                    headers: { 
                        "X-SESSION-TOKEN": UuidStore.value
                    }
                });
                
            cart = await response.json();
            return {
                ...state,
                cart: cart
            };
        default:
            return {
                ...state,
                cart: cart
            };
    }
};

export default CartReducer;

Refactoring Thunk

Create the GET function

Let make the GET a function.

 
async function _getCart() {
    response = await fetch(
        "http://localhost:3333/cart", {
            method: "GET",
            headers: {
                "X-SESSION-TOKEN": UuidStore.value
            }
        });

    cart = await response.json();
    return cart;
}

Wrap the CRUD Functions

Now we create function for each CRUD operation and we wrap it in a function that returns the cart and accepts dispatch and getState as the arguments. Here is ADD.

 
export function addCart(id) {
   return async function addCartThunk(dispatch, getState) {
       await fetch(
           "http://localhost:3333/cart", {
           method: "POST",
           headers: {
               "Content-Type": "application/json",
               "X-SESSION-TOKEN": UuidStore.value
           },
           body: JSON.stringify({
               id: id
           })
       });
       let cart = await _getCart();
       dispatch({type: "refresh". payload: cart });
   }
}

Change Reducer Accept Generic CRUD Functions

Within the original reducer we now have this becase the "refresh" functions passes the action to the refresh function which we will see in a moment.

 
const CartReducer = (state = { cart: [] }, action) => {
    let cart = state.cart;

    switch (action.type) {
        case "refresh": 
            return {
                ...state,
                cart: action.payload
            };
        default:
            return {
                ...state,
                cart: cart
            };
    }
};
export default CartReducer;

Implement new calls to helper functions

Using the this we can create an instance of dispatch and pass the addCart function.

 
...
const dispatch = useDispatch();

<button> type="button" ... onClick={() => dispatch(addCart()event.id)}...</button>

Change UI from Promises Object

We now return an object and now a promise so.

 
        const state = CartStore.getState();
        if (state) {
            state.then((state) = {
                const cart = state.cart;
                const totalAmount = state.cart.reduce((p, n) => p + n.quantity * n.price, 0);
                setCart(cart);
                setTotalAmount(totalAmount);
            }) 
        }
    };

Becomes

 
        const state = CartStore.getState();
        if (state) {
            const cart = state.cart;
            const totalAmount = state.cart.reduce((p, n) => p + n.quantity * n.price, 0);
            setCart(cart);
            setTotalAmount(totalAmount);
        }
    };

Using the Thunk