express-handlebars를 통해 각 page에 대한 middleware(간접접근경로) 생성 :
쉽게 말하면 router, data binding 등의 과정을 express-handlebars 문법으로 제어한다.
기본적으로 express-handlebars는 HTML template를 화면에 구성하는 view engine을 사용한다.
Home 화면을 제외한 나머지 page(router 요청)에 대해 express-handlebars 기능이 적용된다.
app.engine('handlebars', exphbs({defaultLayout: 'main'}))
app.set('view engine', 'handlebars')
먼저 view engine을 express에 구성해준다.
data 정의 및 저장을 get요청이 아닌, 사용자 입력과 post요청을 통해 받도록 구성한다.
별도의 페이지로 이동하여(url get), post request를 통해 data를 제출하는 구조
//post request by ADD is on /tables/add url.
router.get('/add', (req,res)=> res.render('add'))
//DATA ADD by post request
router.post('/add', (req, res) => {
//data add(by get request)
const data = {
title: 'WANTED FOR CPP DEVELOPER',
technologies: 'REACT, JAVA, JAVA SCRIPT',
budget: '$90000',
description: 'SPECIFIC COMPANY A',
contact_email: 'COMPANY_A@gmail.com'
}
post request에 대해, res인자의(request가 성공하였을때 받는 promise인자) body에 post request를 parsing할 수 있도록 구성한다.
const bodyParser = require('body-parser')
//body-parser for post request by form.
app.use(bodyParser.urlencoded({ extended: false }))
handlebars 내부적으로 action, action trigger(method)를 구성하여 준다.
<form action="/tables/add" method="POST">
<div class="input-group">
<label for="title">Title</label>
<input type="text" name="title" id="title" class="input-box" placeholder="eg. Small Wordpress website, React developer"
maxlength="100" value={{title}}>
</div>
앞에서 구성한 body-parser을 통해 req.body와 handlebars의 입력값들의 연결이 가능.
router.post('/add', (req, res) => {
//could parse data by post by bodyparser configuration in app.js
//destructuring data
let {title, technologies, budget, description, contact_email} = req.body
비구조화한 data들을 전달받아, 최종적으로 postgresql table로 제출한다.
//not any issues
//ADD data to table information
Model.create({
title: title,
technologies: technologies,
budget: budget,
description: description,
contact_email: contact_email
})
화면 확인
log 확인
postgresql server 내 data 축적 확인
error 처리 logic을 server side에서 구성한다.
여기서 말하는 error는 submit 전의 공란발생의 경우를 말한다.
공란이 발생하였을 경우 현재 페이지로 re-rendering 되면서 error 메시지가 화면에 출력되도록 구성한다.
기본적으로 client 측에서 발생할 수 있는 모든 경우를 server 측이 고려한다.
- 발생가능한 error(위에서 기술한 공란 발생 등)에 따른 탄력적인 처리가 가능하며
- error 발생이 하지 않도록 유도하는 장치가 server 단에서 마련하도록 한다.
template (post request와 연결하기 위한 구조 구성)
<form action="/tables/add" method="POST">
<div class="input-group">
<label for="title">Title</label>
<input type="text" name="title" id="title" class="input-box" placeholder="eg. Small Wordpress website, React developer"
maxlength="100" value={{title}}>
</div>
java script logic 구성(*post 요청 시 error 분기처리)
//DATA ADD by post request
router.post('/add', (req, res) => {
//could parse data by post by bodyparser configuration in app.js
//destructuring data
let {title, technologies, budget, description, contact_email} = req.body
//server side logic
//not adding required on input attribute,
//but log errors and inform clients to write values.
let errors = []
//Validate fields in server side
if(!title){
errors.push({text: 'Please add title'})
}
if(!technologies){
errors.push({text: 'Please add technologies'})
}
if(!description){
errors.push({text: 'Please add description'})
}
if(!contact_email){
errors.push({text: 'Please add contact_email'})
}
//seperate logic if errors occur or not.
if(errors.length > 0){
//if anything issued
res.render('add', {
errors,
title,
technologies,
budget,
description,
contact_email
})
}else{
//not any issues
//ADD data to table information
Model.create({
title: title,
technologies: technologies,
budget: budget,
description: description,
contact_email: contact_email
})
.then(list => res.redirect('/tables'))
.catch(err=>console.error('ERROR FOUND ', err))
}
})
template level에서 post request가 작동된 후 logic은 다음과 같이 실행한다.
handlebars - #each를 활용하여 error 배열 내부의 객체들을 화면에 구현하도록 구성.
{{#each errors}}
<div class="error">
<p>{{text}}</p>
</div>
{{/each}}
re-rendering 하면서 errors, title, ..과 같은 인자를 비구조화하여 그대로 활용할 수 있다.
<input type="text" name="title" id="title" class="input-box" placeholder="eg. Small Wordpress website, React developer"
maxlength="100" value={{title}}>
server side에서 처리하는 issue logic을 구성한다.
여기서 발생하는 issue는
//budget variable would be given with dollar sign.
//and budget is not required, also it would be controlled.
if(!budget){
budget = 'UNKNOWN'
}else{
budget = `$${budget}`
}
//technologies variable would be given with lowercase
//and space after comma is going to be removed.
technologies = technologies.toLowerCase().replace(/, /g, ',')
위 issue에 대한 logic이 정상작동하는지 확인한다.
화면 확인
postgresql table 확인
Build a Node.js App With Sequelize [3] - Add
https://www.youtube.com/watch?v=6jbrWF3BWM0
body-parser urlencoded option
https://stackoverflow.com/questions/55558402/what-is-the-meaning-of-bodyparser-urlencoded-extended-true-and-bodypar
bodyParser.urlencoded 관련
https://sjh836.tistory.com/154
tag - required
http://tcpschool.com/html-tag-attrs/input-required