Learn JS: FSFS – Simple App Notes


Courses

Updated Jul 5th, 2021

The notes in the post are from the Udemy course titled Learn JS: Full Stack From Scratch. After the “ten days of JS” and “Server Basics” you build simple app#1 before creating a more complex app #2. These are the notes for the simple app.

Section 4: Database Basics
Ch. 22 – 41

Description: Build a Simple To-do List App


Ch. 22 – First Taste of DB

Ch. 23 – Note for Advanced Students

For those of you who are technically savvy, or have a bit of experience with development you may want to work with a “local” database while you’re developing apps. I do not recommend this for beginners; using the “cloud based” database we signed up for in the previous lesson is much simpler and makes the process of “launching” our app publicly a piece of cake. So, unless you consider yourself “advanced” or “experienced” you are safe to stop reading this article and continue to the next lesson.

Ch. 24 – CRUD: Actually Working with a Database

Ch. 25 – Initial Setup for App #1

Ch. 26 – Save Time: Automatic Node APP Restarts

Ch. 27 – Quick Note about MongoDB Warning in Command-Line

Ch. 28 – Connecting Node App to Database

Ch. 29 – Solution to Common Database Problem

Ch. 30 – Installing NPM Packages without Stopping/Starting Server/App

Ch. 31 – Reading Data from the Database

Ch. 32 – Updating a Database Item (Part 1)

How can you add a click listener to a button with a class of edit-me inside a list item that may not exist yet?

inside an callback function for the click event listener pass e as argument and inside the block have if statement that checks if
e.target.classList.contains(‘edit-me’)

this works for any button with ‘edit-me’ class so we want to add a data-id custom attribute and add in a template literal ${item}

Ch. 33 – Updating a Database Item (Part 2)

Send data to the server without submitting a form (fetch or axios)

axios.post(a, b).then().catch()

promises are useful when you don’t know how long an action takes (alternative to callback function approach)

crud methods:
findOneAndUpdate(yourDocToUpdate, {set:{yourField: yourValue}}, callbackFN)

where yourDoc to update is {_id: new mongodb.ObjectID(req.body.id)}

Adjust html template to include id in HTML on opening button tag add data-id and set to equal ${item._id}. Will now see in view>source

In browser.js in axios request line make sure you are sending data-id value for anything that is clicked on. id: e.target.getAtrribute(‘data-id’)

how do we know which item to update?

access via e.target.parentElement.parentElement.querySelector(“item-text”).innerHTML = userinput

Web browser function prompt(“message here”)

pre-populate prompt

add second argument to prompt function
e.target.parentElement.parentElement.querySelector(“item-text”).innerHTML

make sure hitting cancel on prompt does not set to item to blank.

if (userinput) {
axios request
}

Ch. 34 – Deleting a Database Item

deleting is very similar to the updating

literaly duplicate the code and swap

confirm(“your confirm text”) web browser feature put in if statement

in .then(e.target.parentElement.parentElement.remove())

in server-side use deleteOne(yourDocToDelete, callbackFn)

Ch. 35 – Create a New Item Without Page Reload

rework create-field

let createField = doc.getEBId(“create-field”)

in server-side code add res.send() in place of res.redirect()

insertAdjacentHTML(“beforeend”, yourFNToReturnHTML)

in create-item route’s callbackFN pass err, info and in block have res.json(info.ops[0]) to send back JS that represents new mongodb doc that was just created.

in browser.js pass this data as response.data to yourFNToReturnHTML function in the insertAdjacentHTML fn and pass as parameter in the fn definition so you can use ${item.text} in the function body.

Ch. 36 – Client-Side Rendering

Don’t want to refresh entire page every time an item is created.

html was in server.js then used browser code to send axios req to update without page refresh. SO duplicated in browser.js

CSR will help clean up duplication created in prev lesson

CSR the server sends raw data and the browser handles. off-loading html generation to the browser.

in script tags let items = ${JSON.stringify(items)}

delete the code between opening and closing ul in server.js

will now see the raw data in the source

create initial page load render to inject into UL with insertAdjacentHTML()

use .join(“”) to convert array to string of text remove default separation of commas

Ch. 37 – Security

Make sure app is ready for deployment (basic pw protection and insurance polciy with sanitize-html)

Simple pw protection with browser’s built in

create function passwordProtection() and ultimately have as custom middleware using app.use() since you want all of your routes to be protected.

res.set(‘WWW-authenticate’, ‘Basic realm=”yourAppName”‘)

then have if statement (req.headers.authorization == “”) { next()} else {
res.status(401).send(“Authorization required.”)}

When the user types in their username and pasword using the browser’s built in prompt with WWW-authenticate it will encoded into base-64 format

Log your target username and password into the console by typing into the prompt and then opy this from the console to the if statement to confirm match.

need to sanitize so someone cannot add a link with a onclick function into your form. Template engine’s help with this but we are not using that with this simple app.

detect html or JS in an input, leverage a package called sanitize-html by installing and in “/create-item” route create a variable called safeText and set equal to sanitizeHTML(a, b)

where a is text you want to clean up like req.body.text

where b is {allowedTags: [], allowedAtributes: {}}

now in the insertOne mongodb function use safeText variable.

Duplicate code for the “/update-item” route

Ch 38 – Quick Note for Mac users

Ch. 39 – Note for GitHub users

Ch. 40 – Pushing Simple App onto the Web

using heroku and heroku-cli

check if you have git with git –version

When first using git
git config –global user.name “yourName”
git config –global user.email “yourEmail.com”

Create new app with unique name

connect heroku cli to your terminal using heroku login command in terminal

Add a procfile file in your root folder with a line of code inside of web: node server.js where “server.js” is the main entry file that powers your application

Need to make port in code dynamic by creating a port variable and setting to process.env.PORT then add an if statement

if (port == null || port ==””) {port = 3000}

create .gitignore and add node-modules
git init
git add -A
git commit -m”Our first commit”
heroku git:remote -a nameOfYourHerokuApp

git push heroku master

Ch. 41 – Pushing future changes

make a commit and then git push heroku master

Ch. 42 – What’s Next?

Our App lacks: org, unique data per user, attention to detail

zero organization: only two files and these were a mess

unique data per user: only one user account and all users are sharing one account. Need to let users create and account and only see the data specific to them

attention to detail: form validation, thingk of every possibility of what can go wrong and be able to withstand, general security, etc.

We are now familiar with using the web browser to send requests to a server, using express to create a server that listens for requests, and performing CRUD actions on a database.