Year #2, Week #3 đť đď¸
New stuff we learned this week: đ¤
Javascript: Spread Syntax
- the spread syntax in javascript allows you to expand arrays and objects:
const kids = ["Tabitha", "Charlie"];
const parents = ["Frank", "Stacey"];
// đ use spread to create a new bigger array
const artinians = [...parents, ...kids];
// > ['Frank', 'Stacey', 'Tabitha', 'Charlie']
- spreading an array is equivalent to listing each item one by one. So this:
const langs = ["Typescript", "Rust", "Erlang"];
const langsCopy = [...langs];
- is exactly the same as if we did this:
const langs = ["Typescript", "Rust", "Erlang"];
const langsCopy = [langs[0], langs[1], langs[2]];
- spreading an object works about how you would expect, it expands into keys and values in the new object:
const wilhite = {
lastname: "Henderson",
address: "8206 Wilhite",
};
const stalin = {
...wilhite,
firstname: "Stalin",
};
// đ the `wilhite` object got SPREAD into `stalin`, making:
// {
// lastname: "Henderson",
// address: "8206 Wilhite"
// firstname: "Stalin"
// }
- when youâre spreading arrays, you can always add your own items:
const costaDogs = ["Chester", "Caeser"];
const msfDogs = [...costaDogs, "Fern", "Stella"];
- when you are spreading objects, you can override spread properties by supplying them AFTER the
const jared = {
name: "jared",
age: 41,
hasBeard: true,
};
// đ look! overriding the `hasBeard` prop
const beardlessJared = {
...jared,
hasBeard: false,
};
Javascript: Shorthand Object Properties
- take a look at this bit of code:
const name = "jared"
const age = 41;
const hasBeard = true;
const person {
name: name,
age: age,
hasBeard: hasBeard,
};
- lines 6-8 of the above example are kind of a bummer, they are repeating the same thing for the property name as the variable containing the value we want. Thankfully, Javascript provides a shorthand syntax for this situation. It works like this: _if the property name youâre trying to set is the same as a variable you have that holds the value, you can omit the property name like this:
const name = "jared"
const age = 41;
const hasBeard = true;
const person {
name,
age,
hasBeard,
};
- this works anywhere you are creating or using an object, so these examples all work:
function foo() {
console.log("Foo");
}
module.exports = { foo };
const Btn: React.FC = () => {
const color = red;
return <button style={{ color }}>Hi</button>;
};
Javascript: Truthy vs Falsy
- in computer programming, forcing one TYPE to become another type is called COERCION. The most important type coercion to understand (because itâs very common) is boolean coercion.
- you can force any value to become a
boolean
by wrapping it in theBoolean
function:Boolean("hello")
. This coerces the value inside will become eithertrue
orfalse
. - because a boolean value can only be
true
orfalse
every value in javascript falls into one of two categories: values that coerce totrue
and values that coerce tofalse
. These two categories are usually referred to as truthy and falsy. - the easiest way to remember what is truthy and what is falsy is by memorizing what
is falsy. There are only a few values that are falsy, so by definition, everything
else is truthy. Here are the
falsy
values in javascript:
// "falsy" values:
false;
0;
0n; // 0 as "Big Integer" -- a new language feature
``; // empty string
null;
undefined;
NaN; // Not a Number
- most everything on that list makes sense, the only real âgotchasâ are
0
and the empty string. These are a bit counter-intuitive, and they can cause real bugs if youâre not careful. Itâs also a bit sad that an empty array[]
is truthy â it feels like it might be better if it were falsy. - when conditional logic is evaluated in javascript (stuff like
if
,else
andternary
statements), the test expressions are coerced to be a boolean first:
let myName = "";
if (myName) {
// will this line execute?
// is `myName` truthy or falsy?
}
Javascript: Logical OR Operator
- in javascript
||
is the Logical OR operator. Very early on, we learned it for use in conditional tests, like this:
if (x === 3 || x === 5) {
// do something
}
- in an example like the above, itâs pretty easy to understand, it works just like it reads in English: âIf x is 3 OR x is 5âŚâ.
- but there is a bit more to this operator. The way it truly works is this, considering the syntax:
expr1 || expr2
- if
expr1
is truthy, the result or return of the whole expression isexpr1
. Otherwise the result isexpr2
. That means that you can use the||
operator outside of conditionals like this:
let x = true || 5;
- the way to think about the above expression is like this:
- first look at the left side (which is
true
) - is it truthy? (yes, because
true
is truthy) - therefore, the result of the expression is the LEFT SIDE, which is
true
- so,
x
istrue
;
- first look at the left side (which is
- in the same way, consider this expression:
let y = undefined || "hello";
- the way to think about the above expression is like this:
- first look at the left side (which is
undefined
) - is it truthy? (no, because
undefined
is falsy) - therefore, the result of the expression is the RIGHT SIDE, which is
"hello"
- so,
y
is"hello"
;
- first look at the left side (which is
Javascript: Object bracket notation
- the most common way to access object properties is using dot notation:
const dog = {
name: "Fern",
bitesKids: true,
};
let name = dog.name; // "Fern"
- but you can also access object properties using square bracket notation with string keys:
const dog = {
name: "Fern",
bitesKids: true,
};
let name = dog["name"]; // "Fern"
let bites = dog["bitesKids"]; // true
- usually, itâs preferable to use dot notation, it looks nicer and itâs less to type. But objects can have keys that donât allow you to use dot notation:
const dog = {
"first-name": "Fern",
"bites-kids": true,
};
// đ¨ Syntax error
// let name = dog.first-name;
let name = dog["first-name"]; // "Fern"
- in the above example, youâre not allowed to do
dog.first-name
â the hyphen-
makes it invalid javascript. Notice also that I had to put quotes around the property names when I declared the object as well. - finally, when you have a property name (string) as a variable you have to use the variable inside of square bracket notation:
const dog = {
name: "Fern",
bitesKids: true,
};
let randProp = Math.random() < 0.5 ? "name" : "bitesKids";
let randValue = dog[randProp]; // "Fern" OR true
Javascript: Object.keys() / Object.values()
- the global
Object
object has a bunch of useful static methods on it. One very useful one isObject.keys(<someObj>)
- which returns an array of all of the KEYS of an object:
const person = {
name: "Jared",
age: 41,
hasBeard: true,
};
// -> ['name', 'age', 'hasBeard']
Object.keys(person);
- a common pattern is to use
Object.keys()
combined withArray.forEach()
to do something with each pair of values in an object:
const person = {
name: "Jared",
age: 41,
hasBeard: true,
};
Object.keys(person).forEach(key => {
const val = person[key]; // đ get the value for this key
console.log(`${key} is ${val}`);
});
- also useful, (although usually a bit less often used) is
Object.values()
which returns an array of the objects VALUES, which is sort of the opposite ofObject.keys()
:
const person = {
name: "Jared",
age: 41,
hasBeard: true,
};
// -> ["Jared", 41, true]
Object.values(person);
Useful Links:
Homework Plan
- 2 day review all flashcards
- 2 day touch typing practice
- 8 days Execute Program homework (2 weeks)
- 1 day âtidbitsâ homework
- 2 day React Homework
Homework (week 1)
Homework (week 2)
Tidbits Homework
- slowly and carefully (remember sad Jared writing all of this in his office each week!) review the âNew Stuffâ above ^^^.
ssh
in to the HTC pi and make a new dir:~/y2-w3
- fork this repo, and clone your fork into the
~/y2-w3
dir you made above, then connect with vscode - make a new branch!!
- install your dependencies
- run
npm run test
ornpm run test:watch
to run the tests (they will all be failing) - edit
./src/tidbits.spec.ts
until all of the tests are passing - after the tests are all passing, continue down and fill in the answers to the two sections below
- commit your work, create a MR, slack me the MR so I can check your work.
React Homework
- do the Tidbits homework first đ
- slowly and carefully review all of the React items from week 2 homework
- play around with this example website. Try out the two buttons, see what they do. Youâre going to be making a copy of this website. (Donât get scared, you have 2 weeks, and itâs not that bad, I have hints below!)
- read all of the requirements and hints below before starting
- fork this repo, clone your fork into
~/y2-w3
, connect with vscode - install dependencies, fire up your dev server, and forward your ports
- hints and requirements
- the three colors I use in the example are:
- lightest gray:
#eaeaea
- darker gray:
#ccc
- blue:
#5f8c9e
- lightest gray:
- you must have (at least) 3 components:
App.tsx
(file is already created for you), plus anAudio.tsx
and aButton.tsx
- only the
App
component will useuseEffect
to fetch an array of data. The code to do this will be almost identical to theapi.cats.com
example in the week 2 âNew Stuffâ linked above. - the api url you will need to fetch is:
https://api.friendslibrary.com/app-audios
- your
App
component will need to have some state â an array of audio data. Set the initial value to an empty array. When the API response comes back, set the state so that itâs the array of json-decoded data. Again, this is almost identical to the example. - your
App
component will need to map over the array of audios, passing props to theAudio
component. - you will want to
console.log
over what comes back from the API, so you can figure out how to pass the right props to theAudio
component. The images I used are one property of each audio data object. - the
Audio
component will useuseState
twice â once to keep track of if that audio has been âreadâ, and one to keep track if it has been removed. - the
Button
component must take a prop calledprimary
which is a boolean. If this prop is true, it should display blue, like the âMark as readâ button. If this prop is false, it should display like the white âremoveâ button. Use thestyle
prop to accomplish this inside theButton
component - the
Button
prop will also need to accept a prop which is a function to be called when it is clicked. Use the typescript type:() => any
in yourProps
type. TheButton
component will have no state, it is dumb, it will just call whatever function you pass it as a prop, whenever it is clicked. TheAudio
component will pass a different function to theButton
component for each of the two times its used. - to âremoveâ an audio when the user clicks âremoveâ you donât have to actually remove it, you should just fake it by hiding the component with CSS via the style propâŚ
- take baby steps!! I recommend working in small chunks, committing everytime you get a small thing working. Here are examples of the baby steps I would use:
- get the dev server up and forward my ports, make sure itâs visible
- get the
useEffect
API call in<App />
working, console.log out the result - setup the state for App.tsx, setting an
audios
variable usinguseState
- map over the audios, rendering just the title of each audio, so you have a list of audios.
- create the Audio component, decide what props you need
- get the audio component looking good without the buttons
- create the button components without a click handler, get it looking good when the
primary
prop is true or false - wire up the click handlers
- the three colors I use in the example are:
Execute Program Homework
- same as last week (except you donât have to register now)
- no more than 3 lessons per day
- at least one lesson on four different days of the week