Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 6 additions & 12 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,24 @@
const path = require('path');
const path = require('path');

const express = require('express');
const bodyParser = require('body-parser');

const adminData = require('./routes/admin');
const adminRoutes = require('./routes/admin');
const shopRoutes = require('./routes/shop');
const rootDir = require('./util/path');
const errorController = require('./controller/error');

const app = express();

// no need to register the engin, as exoress auto register it
app.set('view engine', 'ejs');
app.set('views', 'views');

app.use(bodyParser.urlencoded({extended : true}));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(rootDir, 'public')));

app.use('/admin',adminData.routes);
app.use('/admin', adminRoutes);
app.use(shopRoutes);

app.use((req, res, next) => {
res.status(404);
res.setHeader('Content-type','text/html');
// passing the argument to templating engine doesnt change, it remains the same
// "path: 'Error'" we passed becasue ejs engin will check "path" argument in naviagation bar logic of template. if we will not provide, we will get an error
res.render('404', {pageTitle: "404", path: 'Error'});
});
app.use(errorController.get404);

app.listen(3000);
5 changes: 5 additions & 0 deletions controller/error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
exports.get404 = (req, res, next) => {
res.status(404);
res.setHeader('Content-type', 'text/html');
res.render('404', { pageTitle: "404", path: 'Error' });
};
29 changes: 29 additions & 0 deletions controller/products.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const Product = require("../model/product");

exports.getAddProduct = (req, res, next) => {
res.render("addProduct", {
path: "admin/add-product",
pageTitle: "Add Products",
activeAddProduct: true,
formsCSS: true,
productCSS: true
});
};

exports.postAddProduct = (req, res, next) => {
const product = new Product(req.body.title);
product.save();

console.log("admin.js ", product);
res.redirect("/");
};

exports.getProduct = (req, res, next) => {
Product.fetchAll((products) => {
res.render("shop", {
pageTitle: "Shop",
prods: products, path: "/"
});
})
};

1 change: 1 addition & 0 deletions data/products.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"title":"book"},{"title":"fds"},{"title":"dfgh"},{"title":""},{"title":""}]
47 changes: 47 additions & 0 deletions model/product.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const fs = require('fs');
const path = require('path');

const rootDir = require('../util/path');

// now we will refactore the code, ie reuse the code(or improve the exisiting code)
const p = path.join(rootDir, 'data', 'products.json');

// craerting common function to extrat data from file
const getProductsFromFile = (cb) => {
fs.readFile(p, (err, fileContent) => {
// as we want only one command to exetue based on condition, not both
// if(err) {
// cb([]);
// } else {
// cb(JSON.parse(fileContent));
// }
// OR
if(err) {
return cb([]);
}
return cb(JSON.parse(fileContent));

});
}


module.exports = class Product {

constructor(t) {
this.title = t;
}

save() {
getProductsFromFile((products) => {
products.push(this);

fs.writeFile(p, JSON.stringify(products), (err) => {
console.log(err);
});
})
}

static fetchAll(cb) {
getProductsFromFile(cb);
}
}
40 changes: 2 additions & 38 deletions notes.txt
Original file line number Diff line number Diff line change
@@ -1,38 +1,2 @@
express js is all about middleware
ie, incoming request will passthrough bunch of functions
thus, there will be more than request handler.
it helps in code segreation



we can have same url for more then one webpage till the time method ccessing that webpages are different
eg: /admin/add-products => GET
/admin/add-products => POST
routes.get('/add-products', (req, res, next) => {
routes.post('/add-products', (req, res, next) => {



res.sendFile('/views/addProducts.html');
this will cause error, as node will check for a file from root directory of and not from
root directory of the project
thus, "path" module will be used to specify the path to html files.



<link rel="stylesheet" href="/public/css/main.css">
this will not work as node will not allow us to acces us the internal files on the browser
ie, localhost:300/public/css/main.css

to access these static files, we have to modify our main app.js file
we need to serve files statically and stically simply means that its not handles by
router or expressjs or any other middleware.
but should be directly forwarded to file sysytem


installing templating engines
npm install --save ejs pug express-handlebars


pug:
html syntax is different but if we inspect page, it will shows us proper html code
7.099
model/product.js
19 changes: 6 additions & 13 deletions routes/admin.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@

const path = require('path');

const express = require('express');

const rootDir = require('../util/path');
// no more using html pages, as we are using ejs engine
// const rootDir = require('../util/path');
const productsController = require('../controller/products');

const routes = express.Router();
const products = [];

routes.get('/add-product', (req, res, next) => {
res.render('addProduct', {path: "admin/add-product", pageTitle : 'Add Products', activeAddProduct: true, formsCSS: true, productCSS: true})
});
routes.get('/add-product', productsController.getAddProduct);

routes.post('/add-product', (req, res, next) => {
products.push({'title' : req.body.title});
console.log('admin.js ', products);
res.redirect('/');
});
routes.post('/add-product', productsController.postAddProduct);

module.exports.routes = routes;
module.exports.productArr = products;
module.exports = routes;
12 changes: 2 additions & 10 deletions routes/shop.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,10 @@ const path = require('path');

const express = require('express');

const adminData = require('./admin');
const productsController = require('../controller/products');

const routes = express.Router();

routes.get('/', (req, res, next) => {
// "layout: false" is speacial keyword which is understood by handlerbars which tells us that we are not using anhy layouts. thus no error regarding layouts will pop up.
// res.render('shop', {pageTitle: 'Shop', prods : adminData.productArr, path : '/', hasProducts : adminData.productArr.length > 0, layout: false});

res.render('shop', {pageTitle: 'Shop', prods : adminData.productArr, path : '/', hasProducts : adminData.productArr.length > 0, activeShop: true, productCSS: true});

console.log('shop.js ', adminData.productArr);
});
routes.get('/', productsController.getProduct);

module.exports = routes;

10 changes: 0 additions & 10 deletions views/shop.ejs
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
<!-- ejs doesnt use concepts of layouts, where there will be one main file and other files can render it -->
<!-- so we use partials, ie some html files which can be used any where in other html files -->

<!-- to render html code from the file, we use "<%- " -->
<!-- if we will use "<%=" then it will render html code as text, instead of html code -->
<%- include('./includes/head.ejs') %>
<link rel="stylesheet" href="/css/product.css">

<%- include('./includes/navigation.ejs') %>
<main>
<!-- if condition -->
<!-- as if is condtion, we are not ooutput any dynamic content, thus no "=" sign after "%" sign -->
<!-- uses same vanialla js syntax, opening and closing braces -->
<% if (prods.length > 0) { %>
<div class="grid">
<!-- for loop -->
<% for (let product of prods) { %>
<article class="card product-item">
<header class="card__header">
<!-- accces the product titile -->
<!-- here as we are assessing the title of product dynamicaly, we are using "=" sign after "%" sign -->
<h1 class="product__title"><%= product.title %></h1>
</header>
<div class="card__image">
Expand Down