1
\$\begingroup\$

I need help in making this as short as possible and it should follow the latest ES6 standards. It it already 100% working. But I need help because i want to follow the best practices in using ES6. The code is a little bit long and messy so maybe you can help me edit my code to make it short and clean. I'm just beginning to learn ES6 so i badly needed your professional advice. Specifically, I want help in implementing on how to output table correctly and declaring variables using ES6.

const products = [];
const cart = [];
const inputs = {
  id: document.getElementById("productID"),
  desc: document.getElementById("product_desc"),
  qty: document.getElementById("quantity"),
  price: document.getElementById("price")
};
const productsTable = document.getElementById("products-table");
const cartsTable = document.getElementById("carts-table");

function renderProductsTable() {
  // delete all entries
  [].slice.call(productsTable.children, 1).forEach(entry => productsTable.removeChild(entry));

  products.forEach(product => {
    const tr = document.createElement('tr');
    const id = document.createElement('td');
    id.textContent = product.id;
    const desc = document.createElement('td');
    desc.textContent = product.desc;
    const qty = document.createElement('td');
    qty.textContent = product.qty;
    const price = document.createElement('td');
    price.textContent = product.price;
    const action = document.createElement('td');
    const deleteButton = document.createElement('button');
    deleteButton.textContent = 'Delete';
    deleteButton.addEventListener('click', removeProduct.bind(null, product.id));
    const addToCartButton = document.createElement('button');
    

    action.appendChild(deleteButton);
   

    tr.appendChild(id);
    tr.appendChild(desc);
    tr.appendChild(qty);
    tr.appendChild(price);
    tr.appendChild(action);
    productsTable.appendChild(tr);
  });
}

function addProduct() {
  const product = {
    id: inputs.id.value,
    desc: inputs.desc.value,
    qty: inputs.qty.value,
    price: inputs.price.value
  };
  console.log(products);

  products.push(product);
  renderProductsTable();
  document.getElementById('order').reset();
}
function removeProduct(product_id) {
  const product = products.find(p => p.id === product_id);
  const index = products.indexOf(product);
  products.splice(index, 1);
  renderProductsTable();
}
<!DOCTYPE html>
<html>
<head>
  <title>Shopping Cart ES6</title>
</head>
<body>
  <form name="order" id="order">
    <table>
      <tr>
        <td>
          <label for="productID">Product ID:</label>
        </td>
        <td>
          <input id="productID" name="product" type="text" size="28" required/>
        </td>
      </tr>
      <tr>
          <td>
              <label for="product">Product Desc:</label>
          </td>
          <td>
              <input id="product_desc" name="product" type="text" size="28" required/>
          </td>
      </tr>
      <tr>
          <td>
              <label for="quantity">Quantity:</label>
          </td>
          <td>
              <input id="quantity" name="quantity" width="196px" required/>
          </td>
      </tr>
      <tr>
          <td>
              <label for="price">Price:</label>
          </td>
          <td>
              <input id="price" name="price" size="28" required/>
          </td>
      </tr>
  </table>
  <input type="reset" class="resetbtn" value="Reset" />
  <input type="button" id="btnAddProduct" onclick="addProduct();" value="Add New Product" >
</form>
<table border="1|1" id="products-table">
  <tr>
    <th>Product ID</th>
    <th>Product Description</th>
    <th>Quantity</th>
    <th>Price</th>
    <th>Action</th>
  </tr>
</table>
<br />
</body>
</html>

\$\endgroup\$
  • 2
    \$\begingroup\$ The guidelines here say that you should describe in your description what exactly your code is supposed to do. \$\endgroup\$ – jfriend00 Jul 10 '17 at 13:32
  • \$\begingroup\$ @jfriend00. I just need help in revising my codes to adhere to the ES6 Standards. Maybe you can help me with that. Thank you. \$\endgroup\$ – Thomas Jul 10 '17 at 13:35
4
\$\begingroup\$

as mentioned previously you are using a lot of ES6 already but you can clean things up a bit more and you seem to want to see it written so here is my attempt below.

I have added in what has been mentioned already as well as some other ES6 helpfullness such as string interpolation.

I have also added in a small bit of validation so that the product id is unique, should be expanded upon but is a start.

https://jsfiddle.net/hpyj1acs/

JavaScript

function renderProductsTable(e) {
    // delete all entries
    [...productsTable.children].slice(1).forEach(entry => productsTable.removeChild(entry));

    products.forEach(product => {
        let tr = document.createElement('tr');
        tr.innerHTML = `<td>${ product.productId }</td>
                        <td>${ product.desc }</td>
                        <td>${ product.qty }</td>
                        <td>${ product.price }</td>
                        <td>
                            <button id="${ product.productId }">Delete</button>
                            <button id="${ product.productId }">Add to Cart</button>
                        </td>`;

        productsTable.appendChild(tr);

        document.getElementById(product.productId).onclick = () => removeProduct(product.productId);
    });
}

function validProduct(){
    let productIsValid = true;
    products.forEach(product => {
        if(Object.values(product).includes(inputs.productId.value)){
            productIsValid = false;
        }else{
            productIsValid = !!(inputs.productId.value && inputs.desc.value && inputs.qty.value && inputs.price.value)
        }
    });
    return productIsValid;
}

function addProduct() {
    if(validProduct()){
        const product = {
            productId: inputs.productId.value,
            desc: inputs.desc.value,
            qty: inputs.qty.value,
            price: inputs.price.value
        };
        console.log(products);

        products.push(product);
        renderProductsTable();
        document.getElementById('order').reset();
    }
}

function removeProduct(product_id) {
    const index = products.findIndex(p => p.id === product_id);
    products.splice(index, 1);
    renderProductsTable();
}

const products = [];
const cart = [];
const inputs = {
    productId: document.getElementById("productID"),
    desc: document.getElementById("product_desc"),
    qty: document.getElementById("quantity"),
    price: document.getElementById("price")
};
const productsTable = document.getElementById("products-table");
const cartsTable = document.getElementById("carts-table");

document.getElementById('btnAddProduct').onclick = addProduct;

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Shopping Cart ES6</title>
</head>
<body>
<form name="order" id="order">
    <table>
        <tr>
            <td>
                <label for="productID">Product ID:</label>
            </td>
            <td>
                <input id="productID" name="product" type="text" size="28" required/>
            </td>
        </tr>
        <tr>
            <td>
                <label for="product">Product Desc:</label>
            </td>
            <td>
                <input id="product_desc" name="product" type="text" size="28" required/>
            </td>
        </tr>
        <tr>
            <td>
                <label for="quantity">Quantity:</label>
            </td>
            <td>
                <input type="number" id="quantity" name="quantity" width="196px" required/>
            </td>
        </tr>
        <tr>
            <td>
                <label for="price">Price:</label>
            </td>
            <td>
                <input type="number" id="price" name="price" size="28" required/>
            </td>
        </tr>
    </table>
    <input type="reset" class="resetbtn" value="Reset" />
    <input type="button" id="btnAddProduct" value="Add New Product" >
</form>
<table border="1|1" id="products-table">
    <tr>
        <th>Product ID</th>
        <th>Product Description</th>
        <th>Quantity</th>
        <th>Price</th>
        <th>Action</th>
    </tr>
</table>
<br />
</body>
</html>
\$\endgroup\$
  • \$\begingroup\$ Wouldn't it make sense to use HTML5 inputs like number for quantity and price (where for price, the step could be 0.01) \$\endgroup\$ – Icepickle Jul 12 '17 at 21:57
  • \$\begingroup\$ @Icepickle you are correct, I have added the number type in. \$\endgroup\$ – Chris Wright May 7 at 11:14
3
\$\begingroup\$

You are already using quite a lot of ES6 features (const, arrow functions, Array.prototype.find, etc)

Here's a few more places you could use some ES6 features:

Array.prototype.findIndex / Array.prototype.filter

Inside removeProduct you are finding the product that has the same id as product_id and then finding the index of that through indexOf - this can be simplified through findIndex:

const index = products.findIndex(p => p.id === product_id)

Alternatively, we could just filter products and not worry about the index altogether:

products = products.filter(product => product.filter !== product_id)

Array.from / ...

You can use Array.from or the spread operator to convert the NodeList instead of [].slice.call:

Array.from(productsTable.children).slice(1).forEach(...)

Or, using spread operator:

[...productsTable.children].slice(1).forEach(...)

Arrow function over bind

In my opinion, the following is easier to read than using bind:

deleteButton.addEventListener('click', () => removeProduct(product.id))

Non ES6/General comments

More generally, I'd recommend being consistent with your style of camel case and renaming to productId

I find not abbreviating variable names helps avoid context switch. It's quite clear that desc is description but using p for product can become not so obvious once your codebase increases.

\$\endgroup\$
  • \$\begingroup\$ Sir can you make changes on my code on the snippet. I would gladly appreciate it. Thank you \$\endgroup\$ – Thomas Jul 10 '17 at 16:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.