Posted onEdited onInProject Symbols count in article: 44kReading time ≈40 mins.
Web Developer Bootcamp
1. 快捷键
ctrl shift p : format document
a tab
lorem
ctrl /
inp tab
! 标准html初始化
2. HTML5
HTML is not a version, but a standard.
You can’t turn off HTML5!
inline elements
a anchor
span
generic element
block elements
p paragraph
div division
generic element
hr: a segment line
br: a line break
sup: superscript
sub: subscript
HTML Entities:start with ampersand&, end with semicolon;
greater than:
less than:
Semantic Markup: meaningful markup accessibility
not div, but
main
nav
section
article
aside
header
footer
time
figure
figcaption
Emmet:
child: >
sibling: +
multiplication: *
item numbering: $
table:
tr : table row
td : single data cell
th : single header:
rowspan=”2”
colspan=”2”
thead
tbody
tfoot
form:
empty container for data inputs
specify how and where the data should be sent
action: where the http request should be sent
method: “get” “post”
input:
type:
text
password
email: pattern
url: pattern
color: color picker
file
number:
min
max
step
time
range:
id + label for
name
min
max
value: initial value
step
radio:
one name for a group of radio
id
label for
value 绑定 name
checkbox:
name 选中后属性为on,不选中则没有该属性
id
label for 绑定 id
checked
submit:
value
placeholder
label + input
input id name
label for
button:
type:
submit (default)
button
select:
name
id
option:
value
selected
textarea:
id + label for
name
placeholder
rows
cols
validation:
browser side validation:
html built-in :
required
minlength
maxlength
min
max
pattern : regular expression: a pattern
type:
url
email
tel
javascript
server side validation
3. CSS
cascading style sheets
selector {
property: value;
}
where:
inline style=”color: green” bad!
head style
css file + link :
href
rel=”stylesheet”
color: text color
background-color
font-size:
px : not recommended for responsive websites
CSS selector:
universal selector:
h1 ,h2
id selector:
#signup
class selector:
.tag
descendant selector: (generic descendant)
li a
span a
.tag a
adjacent selector: (immediately after)
h1 + p
direct child: (direct descendant)
div > li
attribute selector:
input[type=”password”]
section[class=”post”]
a[href*=”google”]
contains
pseudo class:
button:hover
.post a:hover
button:active
.post:nth-of-type(2n)
.post:nth-of-type(2n-1)
pseudo element:
h2::first-letter
p::first-line
p::selection
::selection
“cascade”: order matters!
specificity:
The more specific selector wins!
id > class, attribute, pseudo class > element, pseudo element
!important
inherit
CSS box model
content box:
width
height
padding
margin
border
4.JS
loop:
for of: 遍历iterable
for in: object
scope:
var 只限定function scope, 不限定block scope( loop, conditional)
let 限定block scope
const 限定block scope
callback;
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.
//arrow function const double=nums.map((num)=>{ return num*2; });
//arrow function implicit return const double1=nums.map((num)=>{ num*2 }); const double2=nums.map(num=>num*2);
//setTimeOut(function,t) console.log("Hello"); setTimeOut(()=>{ console.log("...Are you still there?") },3000); console.log("I SHOULD BE THE SECOND LINE");
//"sum of all" const total=nums.reduce((total,price)=>total+price)
//"product of all" const total=nums.reduce((total,price)=>total*price)
//"minimum of all" const min=nums.reduce((min,num)=>{ //the return value becomes the next min //num start from nums[1] to nums[n-1] if(min<num){ return num; } return min; })
//reduce with initial value 100 const total=nums.reduce((total,num)=>total+num,100)
synchronous callback:
1 2 3 4 5 6 7 8 9 10
function greeting(name) { alert(`Hello, ${name}`); }
function processUserInput(callback) { const name = prompt('Please enter your name.'); callback(name); }
//select the JavaScript object const toc=document.getElementById("toc") console.dir(toc)
const allImages=document.getElementsByTagName("img") //a HTML Collection, consisting of HTML Elements, not an array console.dir(allImages[0]) for(let image of allImages){ console.log(image.src) } const squareImages=document.getElementsByClassName("square")
//create a promise constfakeRequest=(url)=>{ returnnewPromise((resolve,reject)=>{ const rand=Math.random() setTimeout(()=>{ if(rand>0.7){ resolve("Your fake data here") } reject("Request error") }, 1000) }) }
fakeRequest('/dogs/1') .then((data)=>{ console.log("DONE WITH REQUEST") console.log("Your data is: ",data) }) .catch((err)=>{ console.log("OH NO, ERROR"+err) })
asyncfunctionrainbow(){ awaitdelayedColorChange("red",1000)) //without await, won't see red color because codes happen at the same time!! //with await, first see red, then see orange, ... awaitdelayedColorChange("orange",1000)) awaitdelayedColorChange("yellow",1000)) awaitdelayedColorChange("green",1000)) awaitdelayedColorChange("blue",1000)) awaitdelayedColorChange("indigo",1000)) awaitdelayedColorChange("violet",1000)) return"ALL DONE" } rainbow().then(()=>{ console.log("End of rainbow") })
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
const fakeRequest = (url0 =>{ returnnewPromise((resolve, reject)=>{ const delay = Math.floor(Math.random()*(4500))+500; setTimeout(()=>{ if(delay>4000){ reject("Connection Timeout:(") }else{ resolve(`Here is your fake data from ${url}`) } }, delay) }) } asyncmakeTwoRequests(){ let data1=awaitfakeRequest("/page1") console.log(data1) let data2=awaitfakeRequest("/page2") console.log(data2) }
1 2 3 4 5 6 7 8 9 10
asyncfunctionmakeTwoRequest(){ try{ let data1=awaitfakeRequest("/page1") console.log(data1) let data2=awaitfakeRequest("/page2") console.log(data2) }catch(err){ console.log(err) } }
8.AJAX
request a web API, and get a JSON string in return, instead of HTML, CSS and JavaScript
JSON.parse(string)
JSON.stringify(object)
AJAX? AJAJ!
JSON: JavaScript Object Notation
HTTP Verbs
get //get data through APIs
a GET request cannot have req.body, only req.query
//anytime we have an incoming request app.use((req,res)=>{ console.log("WE GOT A NEW REQUEST!!"); //console.dir(req); //res.send("HELLO, WE GOT YOUR REQUEST! THIS IS A RESPONSE!!"); res.send({ name: "ivn", message: "HELLO WORLD!" }); })
//start listening! app.listen(8080,()=>{ console.log("LISTENING ON PORT 8080"); })
//schema const movieSchema=new mongoose.Schema({ title: String, year:Number, score:Number rating:String }); //name of model, schema constMovie=mongoose.model("Movie", movieSchema); //create a db collection called movies
//make a new JS object const amadeus = newMovie({title:"Amadeus", year: 1986, score: 9.2, rating: "G"});
//save to database collection! amadeus.save();
//insert many Movie.insertMany([ {}, {}, {}, ])
.load
node
.load index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
//return an array; zero, one or many Movie.find({year: {$lt: 1990}}).then(data=>{ console.log(data) })
//findById Movie.findById("")
//updateOne //updateMany Movie.updateMany({title: {$in:["Amadeus","Stand By Me"]}}, {score: 10}).then(res=>console.log(res))
//findOneAndUpdate Movie.findOneAndUpdate()
//remove is deprecated Movie.remove({}) Movie.deleteMany({}) Movie.findOneAndDelete({})
//app.use whenever a request comes in app.use((req,res)=>{ res.send("HIJACKED BY MY APP.USE()") })
app.use(morgan("tiny")) //inject in the middle //app.use(morgan("common"))
app.use((req,res,next)=>{ console.log("THIS IS MY FIRST MIDDLEWARE") next() console.log("THIS IS MY FIRST MIDDLEWARE - AFTER CALLING NEXT()") })
app.use((req,res,next)=>{ console.log("THIS IS MY SECOND MIDDLEWARE") next() })
//to make sure nothing happens after next, return next app.use((req,res,next)=>{ console.log("THIS IS MY FIRST MIDDLEWARE") returnnext() console.log("THIS IS MY FIRST MIDDLEWARE - AFTER CALLING NEXT()") })
constverifyPassword=(req,res,next)=>{ const {password}=req.query if(password==="chickennugget"){ next() } res.send("SORRY YOU NEED A PASSWORD!!!") }
//can have multiple callbacks //not all callbacks will necessarily be executed app.get("/secret",verifyPassword,(req,res)=>{ res.send("My secret: ") })
//custom error handling middleware //if custom error handler is defined, the default one will no longer work, except we add next(err) app.use((err,req,res,next)=>{ console.log("====================") console.log("=======ERROR========") console.log("====================") console.log(err) res.status(500).send("OH BOY, WE GOT AN ERROR!!") next(err) })
19. Mongo Relationships
SQL relationships tables!
one-to-many
primary key User[id]
foreign key Post[user_id]
many-to-many
a third table
Movie[id], Actor[id]
Role[movie_id,actor_id]
One to Few
example: users/accounts => addresses
embed the data directly in the document
mongo add a new _id for each document/schema
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
const userSchema = new mongoose.Schema({ first: String, last: String, addresses:[ { //by default, each address will also have a _id //can be turned off _id: {id: false}, street: String, city: String, state: String, country: String } ] })
One to Many
store refenrences(object id) to document inside the parent
//const Schema=mongoose.Schema; const {Schema}=mongoose; //the ref option tells Mongoose which model to use during population, or the name of the model we are referencing const farmSchema=newSchema({ name:String, city:String, products:[{type: Schema.Types.ObjectId, ref: "Product"}] })
constFarm=mongoose.model("Farm",farmSchema);
const farm=newFarm({name: "Fully Belly Farms", city: "Guinda, CA"}); const melon1=Product.findOne({name: "Goddess Melon"}); const melon2=Product.findOne({name: "Asparagus"}); //not pushing the entire object, but just the id farm.products.push(melon1); farm.products.push(melon2);
const user = newUser({name:"chickenfan99",age:63}) const tweet1=newTweet({text:"omg I love my chicken family!", likes:0}); tweet1.user=user; user.save(); tweet1.save();
//populate: name of the field, not name of the model console.log(Tweet.findOne({}).populate("user")) //only want user.username console.log(Tweet.findOne({}).populate("user","username"))
paradox of choice: rule of thumb
favor embedding unless there is compelling reason not to
needing to access an object on its own is a compelling reason not to embed it
Arrays should not grow without bound.
Don’t be afraid of application-level joins.
Consider the write/read ratio when denormalizing.
denormal: duplicate and store some requently accessed field together with objectId
As always with MongoDB, how you model your data depends - entirely - on your particular application’s data access patterns.
query?
update?
deletion mongoose middleware
query middleware
document middleware
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
//before "findByIdAndDelete", have no access to data deleted farmSchema.pre("findOneAndDelete",asyncfunction(data){ console.log("PRE MIDDLEWARE") console.log(data) })
//after "findByIdAndDelete", have access to data deleted farmSchema.post("findOneAndDelete",asyncfunction(farm){ //console.log("POST MIDDLEWARE") //console.log(data) if(farm.products.length){ const res =awaitProduct.deleteMany({_id:{$in: farm.products}}) console.log(res) } })
On an incoming http request, Express middleware that supports the session checks a particular client cookie and if that particular cookie is found on the http request and is found in the global session object/database, then it adds that session’s stored info to the request object for the http request handler to later use.
So, here’s a typical sequence:
Incoming HTTP request.
Middleware checks for session cookie.
If session cookie not there, then create one and, in the process created a unique id to identify this http client.
In the persistent session store, initialize the session for this new client.
If session cookie is there, then look in the session store for the session data for this client and add that data to the request object.
End of session middleware processing
Later on in the Express processing of this http request, it gets to a matching request handler. The session data from the session store for this particular http client is already attached to the request object and available for the request handler to use.