- This is the code for the recipe project, including css code for the nav bar. It can be found here.
As shown here:
- RULE: When a setState depends on previous state, use a function parameter
this.setState((prevState, props) => {
return {
counter: prevState.counter + 1
};
});
- Another gotcha is that setState is asynchronous, so, when debugging setState, use a callback function, as shown:
this.setState({name: 'Tim'});
//Won't be updated yet
console.log(this.state.name);
//### The right way is below ###
this.setState({name: 'Joe Doe'}, () => {
console.log('Now state is up to date', this.state.name);
});
A component inside of a Route gets 3 props
- match: info about how the url matches the route component
- location: where you are now, similar to window.location
- history: similar to html5 history object, allows explicit changes to the url
withRouter: if a component is not rendered inside of a Route component, you can use withRouter to get route props
render vs component: use render to pass custom props to your component (obs.: the route component can either use render or component, never both)
It can be found here (this is a 13 min video showing an example todo backend app).
- It's a special kind of function which can pause execution and resume at any time
- Created using a *
- When invoked, a generator object is returned to us with the keys of value and done
- Value is what is returned from the paused function using the yield keyword
- Done is a boolean which returns true when the function has completed
-Object.assign: Create copies of objects without the same reference!
Below, some ES2015 methods like Object.assign, Number.isFinite, etc
// Array.from
// Object.assign
// Number.isFinite
function copyObject(obj){
return Object.assign({}, obj)
}
function checkIfFinite(num){
return Number.isFinite(num)
}
function areAllNumbersFinite(arr){
return arr.every(Number.isFinite)
}
function convertArrayLikeObject(obj){
return Array.from(obj)
}
function displayEvenArguments(){
return Array.from(arguments).filter(val => val % 2 === 0);
}
//exponential
2 ** 2
//includes
[].includes( something )
//padStart, padEnd
Async and Await
- Let us write asynchronous code that reads like a synchronous one
- no .then necessary
- Await can only be used inside async functions
- Await pauses the execution of the async function and is followed by a Promise. The await keyword waits for the promise to resolve, and then resumes the async function's execution and returns the resolved value.
- You can think of the await keyword as a pause button (similar to yield with generators)
- if a promise is rejected using await, an error with be thrown so we can easily use a try/catch statement to handle errors
- To make requests in parallel (and faster), just return the promises right away and then simply await the promises once they are done resolving.
- We can also use the Await keyword with Promise.all. More in this udemy video. Also, an example using Promise.all with Async/Await in this exercise
- always returns undefined
example from udemy here
- creates a new array
- iterates through an array
- runs a callback function for each value in the array
- adds the result of that callback function to the new array
- returns the new array
- map always returns a new array of the SAME length
- creates a new array
- iterates through an array
- runs a callback function for each value in the array
- if the callback function returns true, that value will be added will to the new array
- if the callback function returns false, that value will be ignored from to the new array
- the result of the callback will ALWAYS be a boolean
Udemy Reduce exercices here
A closure only exists when an inner function makes use of variables defined from an outer function that has returned. If the inner function does not make use of any of the external variables all we have is a nested function.
Exercices can be found here
Some examples of constructors here using the apply keyword, and making use of others constructors. The video can be found here
Two parts of inheritance:
- Set the prototype to be an object created with another prototype
- Reset the constructor property
function Person(firstName, lastName){
this.firstName = firstName;
this.lastName - lastName;
}
function Student(firstName, lastName){
return Person.apply(this, arguments);
}
//adding a function to the Student prototype
Student.prototype.fullName = function(){
return `The full name is ${this.firstName} ${this.lastName}`;
}
//now using the Object.create
Student.prototype = Object.create(Person.prototype);
//now resetting the constructor property
Student.prototype.constructor = Student;
Below, another inheritance example (also found here):
// 1 - Create a constructor function for a Vehicle. Each vehicle should have a make, model and year property.
function Vehicle(make, model, year){
this.make = make;
this.model = model;
this.year = year;
}
// 2 - Add a function to the Vehicle prototype called start which returns the string "VROOM!"
Vehicle.prototype.start = function(){
return "VROOM!"
}
// 3 - Add a function to the Vehicle prototype called toString which returns the string "The make, model, and year are" concatenated with the make, model and year property
Vehicle.prototype.toString = function(){
return `The make, model, and year are ${this.make} ${this.model} ${this.year}`
}
/* Examples
var vehicle = new Vehicle("Tractor", "John Deere", 1999)
vehicle.toString() // 'The make, model, and year are Tractor John Deere 1999'
*/
// 4 - Create a constructor function for a Car. Each object created from the Car function should also have a make, model, and year and a property called numWheels which should be 4. The Car prototype should inherit all of the methods from the Vehicle prototype
function Car(make, model, year){
Vehicle.apply(this, arguments);
this.numWheels = 4;
}
Car.prototype = Object.create(Vehicle.prototype);
Car.prototype.constructor = Car;
// 5 - Create a constructor function for a Motorcycle. Each object created from the Motorcycle function should also have a make, model, and year and a property called numWheels which should be 2. The Motorcycle prototype should inherit all of the methods from the Vehicle prototype
function Motorcycle(make, model, year){
Vehicle.apply(this, arguments);
this.numWheels = 2;
}
Motorcycle.prototype = Object.create(Vehicle.prototype);
Motorcycle.prototype.constructor = Car;
The same code above can be found here refactored using ES2015 JS
Here are some maps and sets exercises.
Here are they.
Shown here
Some exercises here
Fetch User Profile Generator
const btn = document.getElementById("btn");
const url = "https://randomuser.me/api/";
let avatar = document.getElementById("avatar");
let fullName = document.getElementById("fullname");
let userName = document.getElementById("username");
let userMail = document.getElementById("email");
let userCity = document.getElementById("city");
const fetchNewUser = () =>
fetch(url)
.then(handleErrors)
.then(res => newUser(res.results[0]))
.catch(err => console.log(err));
const handleErrors = res => {
if (!res.status) {
throw new Error(res.status);
}
return res.json();
};
const newUser = ({
picture: { large },
name: { first, last },
login: { username },
email,
location: { city }
}) => {
avatar.src = large;
fullName.innerText = `${first} ${last}`;
userName.innerText = username;
userCity.innerText = city;
userMail.innerText = email;
};
btn.addEventListener("click", fetchNewUser);
<h1 class="title"> Random User Generator</h1>
<div class="user-profile">
<img id="avatar" src="https://pbs.twimg.com/profile_images/743138182607175680/ZJzktgBk_400x400.jpg" />
<div id="fullname">Jon Snow</div>
<div id="username">
kingofnorth
</div>
<div class="description">
<div>Email: <span id="email">[email protected]</span></div>
<div>City: <span id="city">Winterfell</span></div>
</div>
<div class="footer">
<button id="btn">Next User!</button>
</div>
</div>
/* CSS design originally by @jofpin, tweaked by Colt Steele */
@import url(https://fonts.googleapis.com/css?family=Raleway|Varela+Round|Coda);
body {
background: #ecf0f1;
padding: 2.23em;
}
.title {
color: #2c3e50;
font-family: "Coda", sans-serif;
text-align: center;
}
.user-profile {
margin: auto;
width: 27em;
height: 11em;
background: #fff;
border-radius: .3em;
}
.user-profile #fullname {
margin: auto;
margin-top: -4.40em;
margin-left: 5.80em;
color: #16a085;
font-size: 1.53em;
font-family: "Coda", sans-serif;
font-weight: bold;
}
#username {
margin: auto;
display: inline-block;
margin-left: 10.43em;
color: #3498db;
font-size: .87em;
font-family: "varela round", sans-serif;
}
.user-profile > .description {
margin: auto;
margin-top: 1.35em;
margin-right: 3em;
width: 18em;
color: #7f8c8d;
font-size: .87em;
font-family: "varela round", sans-serif;
}
.user-profile > img#avatar {
padding: .7em;
margin-left: .3em;
margin-top: .3em;
height: 6.23em;
width: 6.23em;
border-radius: 18em;
}
.footer {
margin: 2em auto;
height: 3.70em;
background: #16a085;
text-align: center;
border-radius: 0 0 .3em .3em;
display: flex;
justify-content: center;
align-items: center;
transition: background 0.1s;
}
button {
color: white;
font-family: "Coda", sans-serif;
text-align: center;
font-size: 20px;
background: none;
outline: none;
border: 0;
}
.footer:hover {
background: #1abc9c;
}
Selection methods:
- d3.select: single element
d3.select(#page-title) .style("background-color","#fff") .attr("class","new-class") .text("d3 is cool")
- d3.selectAll: multiple elements
- d3.selectAll.nodes(): return an array of matching HTML elements
- d3.selectAll.node(): return the first (non-null_ HTML element
Event Listeners
d3.select("h1").on("click", function(){
console.log("Yay event listeners")
}
d3.select("h1").on("click", null) //to remove an event listener