Skip to content

Latest commit

 

History

History

12 - Cart and Auth Helper

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Section 12: Cart and Auth Helper

Adding Item to Cart Helper

When we're developing with separation of frontend and backend, we should keep the extremely separate from the component: "Components should just know about the method which is coming from somewhere and have no idea about who is talking to API."

Keeping the components in separate file make our code more robust as well as more scalable. In this section, we will have a couple of mothods which will be adding things into our cart. Let's edit the cartHelper.js file.

export const addItemToCart = (item, next) => {
  let cart = [];
  if (typeof window !== undefined) {
    if (localStorage.getItem("cart")) {
      cart = JSON.parse(localStorage.getItem("cart"))
    }

    cart.push({
      ...item
    });

    localStorage.setItem("cart", JSON.stringify(cart));
    next();
  }
}

The next is a classic method in the JavaScript and especially in the React world where we use it to provide a callback functionality to anybody who is using this method. But all we care about here is it gives the user a functionality where he can add his own callback and can chain on other things that he want to do.

Furthermore, We can verify whether this is a browser or not by checking the window object. Note that the window object is available only in the browser.

In the end of this section, we can add the addItemToCart function to the Card component.



Load and Remove Items from Cart

Let's say that the user has made a purchase and we need to emptied the cart. In the case, we need to implement another method which will be emptied out the cart.

Now, we're going to add the loadCart(), removeItemFromCart() and cartEmpty() function to the cartHelper.js file.

loadCart Method

export const loadCart = () => {
  if (typeof windows !== undefined) {
    if (localStorage.getItem("cart")) {
      return JSON.parse(localStorage.getItem("cart"));
    }
  }
}


removeItemFromCart Method

export const removeItemFromCart = (productId) => {
  let cart = [];
  if (typeof windows !== undefined) {
    if (localStorage.getItem("cart")) {
      cart = JSON.parse(localStorage.getItem("cart"));
    }

    cart.map((product, i) => {
      if (product._id === productId) {
        cart.splice(i, 1);
      }
    })

    localStorage.setItem("cart", JSON.stringify(cart));
  }
  return cart;
}

Note that we can use product._id or product._id here, both of them are work well. It's a classic thing which is recently updated and escalate as well as in the MongoDB to keep the consistency with the majority (like in many of the modern databases).



cartEmpty Method

export const cartEmpty = next => {
  if (typeof windows !== undefined) {
    localStorage.removeItem("cart");
    let cart = [];
    localStorage.setItem("cart", JSON.stringify(cart));
    next();
  }
}


SignIn and SignUp Helpers.

Our server is ready to make some of the post request where we can do things like signup, signin and signout. What are the things we receive from the server that we are running so that we can just storing it and returning it?

signup Method

export const signup = user => {
  return fetch(`${API}/user/`, {
    method: "POST",
    headers: {
      "Accept": "application/json",
      "Content-Type": "application/json"
    },
    body: JSON.stringify(user)
  })
    .then((response) => response.json())
    .catch(err => console.log(err))
}


signup Method

export const signin = user => {
  const formData = new FormData();

  for (const name in user) {
    formData.append(name, user[name]);
  }

  return fetch(`${API}/user/login/`, {
    method: "POST",
    body: FormData
  })
    .then(response => response.json())
    .catch(err => console.log(err))
}


Signout and Authenticated User

authenticate Method

export const authenticate = (data, next) => {
  if (typeof window !== undefined) {
    localStorage.setItem("jwt", JSON.stringify(data));
    next()
  }
}


isAuthenticated Method

export const isAuthenticated = () => {
  if (typeof window == undefined) {
    return false;
  }

  if (localStorage.getItem("jwet")) {
    return JSON.parse(localStorage.getItem("jwt"));
  } else {
    return false;
  }
}


signout Method

export const signout = next => {
  const userId = isAuthenticated() && isAuthenticated.user.id;

  if (typeof window !== undefined) {
    localStorage.removeItem("jwt");
    cartEmpty(() => { });

    return fetch(`${API}/user/logout/${userId}`, {
      method: "GET"
    })
      .then(response => {
        console.log("Signout success");
        next();
      })
      .catch(err => console.log(err));
  }
}


Handling Private Routes in React

The seciton we're going to talk about how we can restrict some of the routes. Route Restriction is one of the most important thing to do if our application is role based. Let's edit the PrivateRoutes.js file.

const PrivateRoutes = ({ children, ...rest }) => {
  return (
    <Route {...rest}
      render={({ props }) =>
        isAuthenticated
          ? (<Component {...props} />)
          : (<Redirect to={{ pathname: "/signin", state: { from: props.location } }} />)
      } />
  )
}

Then we can add the PrivateRoutes to the Routes.js.