Sunday, August 2, 2020

MERN STACK - Amazona Project Part 3

Multiple items in cart need to be saved in cookies


Cookies setup 


npm install js-cookie

in frontent folder


import Cookie from "js-cookie";

---
const removerFromCart = (productId) => (dispatch, getState) => {
    dispatch({ type: CART_REMOVE_ITEM, payload:productId });

    const { cart: {cartItems } }  = getState();
    Cookie.set("cartItems", JSON.stringify(cartItems));

}

store.js



const cartItems = Cookie.getJSON("cartItems") || [];

const initialState = { cart : {cartItems} };



 


Mongo DB setup



create .env file in the root amazona

MONGODB_URL=mongodb://localhost/amazona

npm install dotenv

Create config.js inside amazon/backend/ 
export default {
    MONGODB_URL: process.env.MONGODB_URL || 'mongodb://localhost/amazona'
}
Add  to server.js

import dotenv from 'dotenv';
import config from './config';

dotenv.config();


Download and install MONGO DB  


Install mongoose  @amazona root

npm install mongoose

Add in server.js 

const mongodbUrl = config.MONGODB_URL;
mongoose.connect(mongodbUrl, {
    useNewUrlParser:true;
}).catch(error => console.log(error.reason));



Create Models/userModel.js in backend


import mongoose from 'mongoose';

const userSchema = new mongoose.Schema({
    name: { type: Stringrequired:true },
    email: { type: Stringrequired: trueunique:true },
    password: { type: Stringrequired:true },
    isAdmin: { type:Booleanrequireddefault: false }
});

const userModel = mongoose.model("User"userSchema);

export default userModel;



Create Routes/userRoute.js  in backend


import express from 'express';
import User from '../models/userModel';

const router = express.Router();

router.get("/api/users/createadmin"async(reqres=> {
    
    try {
        const user = new User({
            name: 'Sreeraj',
            email: 'sreeraj@infoexpo.in',
            password:'12345',
            isAdmin: true
    
        });
        const newUser = await user.save();
        res.send(newUser);
    } catch (error) {
        res.send({ msg: error.message });
    }

});










Thursday, July 30, 2020

VS Code Shortcuts

Commonly usable and helpful VS code editor software shortcuts for programmers.



Find and Open File with file name    :    Ctrl + P

Tuesday, July 28, 2020

Server Side Steps - Ecommerce project - Node JS steps - Using Express JS


  • Create folder - Amazona/backend 

  • Create file server.js


Run npm init in the root folder(amazona)



  • Install Express JS  

npm install express    (root folder)

  • Run the backend

node backend/server.js
error:   code written in ES6 , node only understands es5   --- convert it

ES6 Conversion

npm install @babel/cli @babel/core @babel/node @babel/preset-env nodemon

npm install @babel/cli @babel/core @babel/node @babel/preset-env nodemon --save-dev


Create .babelrc file in the root with below code

{
    "presets": [
        [
            "@babel/preset-env"
        ]
    ]
}


edit package.json

  "scripts": {
    "start""nodemon --watch backend --exec babel-node backend/server.js"
  },



RUN backend using : 

npm start


we can get the json data printed 



Use react hooks to get data from the server

  • create proxy inside the frontent folder

package.json  - add the proxy code


  "name""frontend",
  "proxy""http://127.0.0.1:5000", // add this line
  "version""0.1.0",
 




Go to frontent  - install axios

npm install axios

    const [productssetProduct] = useState([]);

    useEffect(()  => {
      const fetchData = async () =>{
        const {data} = await axios.get("/api/products");
        setProduct(data);
      }
      fetchData();
      return () => {
        //
      };
    }, [])   




trouble shoot network requests


Developer Tools --- Network ---- XHR


State Management using REDUX


Go to /frontent/
npm install redux react-redux






create store with product reducers


  • Wrap the <App /> in index js with
 

const store = createStore(reducerinitialStatecompose(applyMiddleware(thunk)));

//thunk is a redux middleware allows to run async operation in the action in redux


npm install redux-thunk


Add redux tool to dev tools


const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSTION_COMPOSE__ || compose;

  • define constants  -- create constants folder



---- useSelector

 create :   actions ---> productActions.js

redux state , move axios code

   
 return loading ? <div> Loading...</div>:
      error ? <div>{error}</div>:
    <ul className="products">

 




Redux to Product Details Page



Create web api  --- for individual product details



create constansts
create reducers
add to store


Add to Cart & Qty

const [qty, setQty] = useState(1);

                         <li> 
                            Qty: <select value={qty} onChange={(e) => { setQty(e.target.value)} } >
                               {[...Array(product.countInStock).keys()].map(x=>
                                <option key={x+1} value={x+1}>{x+1}</option>
                                )}
                            </select>
                        </li>


Monday, July 27, 2020

HTML to React App -- Convertion Steps

  • Create React App
npx create-react-app app-name


cd  app-name


npm start

Steps of conversion
  • Copy paste css to index.css
  • Copy paste contents inside <body> to App.js  return data
  • Replace "class" with "className"    (since class is a reserved keyword and cannot be used inside the js file)
  • Create images folder inside public then move images to that
  • rename images path   to   /images/name.jpg


Define functions

  const openMenu = () => {
    document.querySelector(".sidebar").classNameList.add("open");
  }
  const closeMenu = () => {
    document.querySelector(".sidebar").classNameList.remove("open");
  }



function call

replace  onclick="closeMenu()" to onClick={closeMenu}


Change onclick to onClick


Add  transition: all .5s;   to css



static to dynamic product list - JSX

<ul className="products">

              {
                data.products.map(product => 
                  <li>
                    <div className="product">
                          <img className="product-image" src={product.image} alt="product" />
                          <div className="product-name"> 
                              <a href="product.html">{product.name}</a>
                          </div>
                          <div className="product-brand">{product.brand}</div>
                          <div className="price"> ${product.price}</div>
                          <div className="product-rating"> {product.rating} Stars ({product.reviewCount} reviews)</div>
                      </div>
                  </li>                
                )
              }
                
            </ul>



Routing in React

npm install react-router-dom


Wrap the return contents in <BrowserRouter> </BrowserRouter>

import { BrowserRouterRoute } from 'react-router-dom';


  • Product page

#root{ height: 100%; }



  • Change the link code / replace <a> with <Link>

<Link to="/"> Amazon Store </Link>

<a href="index.html"> Amazon Store</a>

import {Link} from 'react-router-dom';