JavaScript NodeJS Voting App
Tools
- CSS
- JavaScript
- NodeJS
Packages
- Express
1. Initialize package.json
npm init -y
2. Install Express Dependency
npm i express
3. Build Server
const express = require('express')
const fs = require('fs')
const path = require('path')
const app = express()
const dataFile = path.join(__dirname, "data.json")
const port = process.env.PORT || 3000
app.listen(port, () => {
console.log("Server is running on port 3000")
})
4. Build data.json File
{
"JavaScript": 0,
"TypeScript": 0,
"Both": 0
}
5. Support Posting Form Data with URL encoded
app.use(express.urlencoded({ extended: true}))
6. Create Route
const express = require('express')
const fs = require('fs').promises
const path = require('path')
const router = express.Router()
const dataFile = path.join(__dirname, "../data.json")
router.get('/', (req, res) => {
res.send("Index Route")
})
router.get('/poll', async(req, res) => {
// Return content from JSON data file
let data = JSON.parse(await fs.readFile(dataFile, "utf-8"))
// Return the totals from data Object
const totalVotes = Object.values(data).reduce((total, n) => total += n, 0)
// Get the percentage for each objects value
data = Object.entries(data).map(([label, votes]) => {
return {
label: label,
percentage: `${(((100 * votes) / totalVotes) || 0).toFixed(0)}%`
}
})
res.json({ data })
})
router.post("")
module.exports = router
7. Creatte Client Side Directory
directory structure
- client
- css -- main.css
- js -- main.js
8. Build out styles in main.css
.poll {
width: 400px;
padding: 1.5rem;
margin: 50px;
font-family: sans-serif;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
border-radius: 10px;
}
.poll__title{
font-weight: bold;
font-size: 1.5rem;
margin-bottom: 1.5rem;
}
.poll__option-fill{
width: 50%;
height: 10px;
background-color: #ddd;
}
.poll__option:hover{
cursor: pointer;
}
.poll__option:not(:last-child){
margin-bottom: 0.5rem;
}
.poll__option--selected .poll__option-fill{
background-color: #009578;
}
.poll__option--selected .poll__option-info{
font-weight: bold;
}
.poll__option-info{
display: flex;
justify-content: space-between;
padding:0.5rem 0;
font-size: 0.85rem;
}
9. Inject HTML
class Poll {
constructor(root, title) {
this.root = root
this.selected = sessionStorage.getItem('poll-selected')
this.endpoint = "http://localhost:3000/poll"
this.root.insertAdjacentHTML('afterbegin', `
<div class="poll__title">${ title }</div>
`)
this._refresh()
}
async _refresh() {
const response = await fetch(this.endpoint)
const data = await response.json()
console.log(data)
}
}
const p = new Poll(document.querySelector('.poll'), "Which do you prefer?")
console.log(p)
10. Enable CORS
directory server > routes > Router.js
// Enable CORS Middleware
router.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*")
next()
})