diff --git a/app.js b/app.js index d6a0724..a99b7ef 100644 --- a/app.js +++ b/app.js @@ -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); \ No newline at end of file diff --git a/controller/error.js b/controller/error.js new file mode 100644 index 0000000..5d3d895 --- /dev/null +++ b/controller/error.js @@ -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' }); +}; \ No newline at end of file diff --git a/controller/products.js b/controller/products.js new file mode 100644 index 0000000..7ea184c --- /dev/null +++ b/controller/products.js @@ -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: "/" + }); + }) +}; + diff --git a/data/products.json b/data/products.json new file mode 100644 index 0000000..9d200e9 --- /dev/null +++ b/data/products.json @@ -0,0 +1 @@ +[{"title":"book"},{"title":"fds"},{"title":"dfgh"},{"title":""},{"title":""}] \ No newline at end of file diff --git a/model/product.js b/model/product.js new file mode 100644 index 0000000..04cee55 --- /dev/null +++ b/model/product.js @@ -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); + } +} \ No newline at end of file diff --git a/notes.txt b/notes.txt index d5bb9e7..0869964 100644 --- a/notes.txt +++ b/notes.txt @@ -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. - - - - -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 \ No newline at end of file +7.099 +model/product.js \ No newline at end of file diff --git a/routes/admin.js b/routes/admin.js index 259e70e..c3fe8e1 100644 --- a/routes/admin.js +++ b/routes/admin.js @@ -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; \ No newline at end of file +module.exports = routes; diff --git a/routes/shop.js b/routes/shop.js index a558eea..14e23be 100644 --- a/routes/shop.js +++ b/routes/shop.js @@ -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; - diff --git a/views/shop.ejs b/views/shop.ejs index ca4ba38..4a09fce 100644 --- a/views/shop.ejs +++ b/views/shop.ejs @@ -1,24 +1,14 @@ - - - - <%- include('./includes/head.ejs') %> <%- include('./includes/navigation.ejs') %> - - - <% if (prods.length > 0) { %> - <% for (let product of prods) { %> - - <%= product.title %>