{
  "name": "Alexandru Păvăloi",
  "nickname": "Păvă",
  "age": 25,
  "blog": "https://iampava.com",
  "e-mail": "pava@iampava.com"
}
_iampava

πŸ“ the story so far...

{ about you }

πŸ‘¨β€πŸŽ“πŸ‘©β€πŸŽ“

{ about you }

πŸ”₯ STAW πŸ”₯

Official Lab Page

Official Course Page

By the end of this course you:

πŸ”₯ will have the skills to build not trivial 
Web Apps projects with a strong focus on JavaScript
🀘 will have worked on a personal project which showcases your skills 
πŸ‘¨β€πŸ­ could be ready to venture into the real world and get into a summer job/internship
πŸ˜… will understand why JavaScript is the best language in the world
( probably )

this course will focus on:

βœ… modern JavaScript knowledge

βœ… browser API's

βœ… server side via Node.js

this course will not focus on:

  • Client-side Frameworks
  • SASS/LESS/other pre'processors
  • Performance
  • Build tools
  • Testing
  • GraphQL
  • A11y
  • Microservices
  • Progressive Web Apps
  • Hybrid Apps
  • ...
{

You can expect of me to:

  • Pass this object
    
  • Online support(chat/group)
  • Clean code learning
  • Async learning
  • Best practices
  • I can expect from you to:

  • Solve the exercises/problems weekly
    
  • Silence
  • Insusirea cunostintelor de tw
  • Q&A
  • Try solving the problem before asking

πŸ‘·β€β™‚οΈ

Project*

πŸ“

Course Tests

πŸ“

Lab Tests*

=

final grade

+

+

* mandatory
  • PROJECT

work on something you ❀

ARCHITECTURE | WEEK #9 🀘

fINAL SOLUTION | EXAM WEEK πŸ’ͺ

TEAMS OF 2 || 3 🀝

{

βœ… frameworksΒ  allowed on Node.js

❌ no frameworks on the client

βœ… 3 unannounced tests during the labs
βœ… 1 optional test at the end of the course
πŸ”‘ Get at least 5 for all project components and 5 for the lab exercises in order to pass!

how?

Every Friday I'll post in-advance exercises for the next lab!

Tests will assume you've understood all exercises from there.

Student presentations

πŸ‘¨β€πŸ«πŸ‘©β€πŸ«

email at: pava@iampava.com

VS Code
Git
Firefox & Chrome

One last stop...

OK, let's do this!

HTML

  • <p 
         class="bold" 	      
         data-author="David Smith"
    >
      Content
    </p>
<p 
     class="bold" 	      
     data-author="David Smith"
>
  Content
</p>
tag
attribute
custom attribute

Build this using only HTML

HTML in modern times
  • <div class="card">
      <h1> {{ user.username }} </h1>
      <p class="about"> {{ user.about }} </p>
        <span *ngFor="job in user.jobs" class="chip"> {{ job }} </span>
      <button type="button" *ngIf="user.isAdmin">
        Edit
      </button>
    </div>
<div class="card">
  <h1> {{ user.username }} </h1>
  <p class="about"> {{ user.about }} </p>
    <span *ngFor="job in user.jobs" class="chip"> {{ job }} </span>
  <button type="button" *ngIf="user.isAdmin">
    Edit
  </button>
</div>
  • <div class="card">
      <h1> {{ user.username }} </h1>
      <p class="about"> {{ user.about }} </p>
        <span v-for="job in user.jobs" class="chip"> {{ job }} </span>
      <button type="button" v-if="user.isAdmin">
        Edit
      </button>
    </div>
div class="card">
  <h1> {{ user.username }} </h1>
  <p class="about"> {{ user.about }} </p>
    <span v-for="job in user.jobs" class="chip"> {{ job }} </span>
  <button type="button" v-if="user.isAdmin">
    Edit
  </button>
</div>
  • function cardComponent({ user }) {
      return ( <div className="card">
        <h1> { user.username } </h1>
        <p class="about"> { user.about } </p>
    	{user.jobs.map(job => (
          <span class="chip"> {{ job }} </span>
        ))}
        {user.isAdmin && <button type="button">
          Edit
        </button>
        }
      </div>
      )
    }
function cardComponent({ user }) {
  return ( <div className="card">
    <h1> { user.username } </h1>
    <p class="about"> { user.about } </p>
	{user.jobs.map(job => (
      <span class="chip"> {{ job }} </span>
    ))}
    {user.isAdmin && <button type="button">
      Edit
    </button>}
}
Websites in modern life
Multi Page Apps
Single Page App
Hybrid

V

V

(ex: Wikipedia)
(ex: DevDrive)
(ex: Twitter)

Client only

Server & client

Server Side Rendered
Client Side Rendered
Hybrid

V

V

What makes great HTML?

πŸ—£ a11y | accessibility

Examples of bad html!

  • <h2>
      <div class="btn btn-lg btn-primary btn-rounded px-4 mr-3"                      @click="acceptTeamInvitations(team_invitation)">
        Accept Invitations
      </div>
      <div class="btn btn-lg btn-secondary btn-rounded px-4 mr-3" @click="rejectTeamInvitations(team_invitation)">
        Reject Invitations
      </div>
    </h2>
<h2>
  <div class="btn btn-lg btn-primary btn-rounded px-4 mr-3"                      @click="acceptTeamInvitations(team_invitation)">
    Accept Invitations
  </div>
  <div class="btn btn-lg btn-secondary btn-rounded px-4 mr-3" @click="rejectTeamInvitations(team_invitation)">
    Reject Invitations
  </div>
</h2>
  • <div id="userCardContainer">
      <div id="centeredCardContainer">
        <div id="centeredCard">
          <div id="userDetailsHolder">
            <span id="userName">{{ (userDetails$ | async).FirstName }}</span>
            <img [src]="(userDetails$ | async).PictureProfile" id="menuUserIcon" />
          </div>
        </div>
      </div>
    </div>
<div id="userCardContainer">
  <div id="centeredCardContainer">
    <div id="centeredCard">
      <div id="userDetailsHolder">
        <span id="userName">{{ (userDetails$ | async).FirstName }}</span>
        <img [src]="(userDetails$ | async).PictureProfile" id="menuUserIcon" />
      </div>
    </div>
  </div>
</div>
Custom HTML elements
  • <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Simple word count web component</title>
      </head>
      <body>
        <h1>Word count rating widget</h1>
    
        <article contenteditable="">
          <h2>Sample heading</h2>
    
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc pulvinar sed justo sed viverra. Aliquam ac scelerisque tellus. Vivamus porttitor nunc vel nibh rutrum hendrerit. Donec viverra vestibulum pretium. Mauris at eros vitae ante pellentesque bibendum. Etiam et blandit purus, nec aliquam libero. Etiam leo felis, pulvinar et diam id, sagittis pulvinar diam. Nunc pellentesque rutrum sapien, sed faucibus urna sodales in. Sed tortor nisl, egestas nec egestas luctus, faucibus vitae purus. Ut elit nunc, pretium eget fermentum id, accumsan et velit. Sed mattis velit diam, a elementum nunc facilisis sit amet.</p>
    
          <p>Pellentesque ornare tellus sit amet massa tincidunt congue. Morbi cursus, tellus vitae pulvinar dictum, dui turpis faucibus ipsum, nec hendrerit augue nisi et enim. Curabitur felis metus, euismod et augue et, luctus dignissim metus. Mauris placerat tellus id efficitur ornare. Cras enim urna, vestibulum vel molestie vitae, mollis vitae eros. Sed lacinia scelerisque diam, a varius urna iaculis ut. Nam lacinia, velit consequat venenatis pellentesque, leo tortor porttitor est, sit amet accumsan ex lectus eget ipsum. Quisque luctus, ex ac fringilla tincidunt, risus mauris sagittis mauris, at iaculis mauris purus eget neque. Donec viverra in ex sed ullamcorper. In ac nisi vel enim accumsan feugiat et sed augue. Donec nisl metus, sollicitudin eu tempus a, scelerisque sed diam.</p>
    
          <p is="word-count"></p>
        </article>
    
        <script>
            class WordCount extends HTMLParagraphElement {
              constructor() {
                super();
    
                const wcParent = this.parentNode; // count words in element's parent element
    
                function countWords(node){
                  const text = node.innerText || node.textContent;
                  return text.split(/\s+/g).length;
                }
    
                const count = `Words: ${countWords(wcParent)}`;
    
                const shadow = this.attachShadow({mode: 'open'});
                const text = document.createElement('span');
                text.textContent = count;
                shadow.appendChild(text);
    
                setInterval(function() {
                  const count = `Words: ${countWords(wcParent)}`;
                  text.textContent = count;
                }, 200);
              }
            }
    
            customElements.define('word-count', WordCount, { extends: 'p' });
        </script>
    
      </body>
    </html>
    
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Simple word count web component</title>
  </head>
  <body>
    <h1>Word count rating widget</h1>

    <article contenteditable="">
      <h2>Sample heading</h2>

      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc pulvinar sed justo sed viverra. Aliquam ac scelerisque tellus. Vivamus porttitor nunc vel nibh rutrum hendrerit. Donec viverra vestibulum pretium. Mauris at eros vitae ante pellentesque bibendum. Etiam et blandit purus, nec aliquam libero. Etiam leo felis, pulvinar et diam id, sagittis pulvinar diam. Nunc pellentesque rutrum sapien, sed faucibus urna sodales in. Sed tortor nisl, egestas nec egestas luctus, faucibus vitae purus. Ut elit nunc, pretium eget fermentum id, accumsan et velit. Sed mattis velit diam, a elementum nunc facilisis sit amet.</p>

      <p is="word-count"></p>
    </article>

    <script>
        class WordCount extends HTMLParagraphElement {
          constructor() {
            super();

            const wcParent = this.parentNode;

            function countWords(node){
              const text = node.innerText || node.textContent;
              return text.split(/\s+/g).length;
            }

            const count = `Words: ${countWords(wcParent)}`;
            const shadow = this.attachShadow({mode: 'open'});
            const text = document.createElement('span');
            
            text.textContent = count;
            shadow.appendChild(text);

            setInterval(function() {
              const count = `Words: ${countWords(wcParent)}`;
              text.textContent = count;
            }, 200);
          }
        }

        customElements.define('word-count', WordCount, { extends: 'p' });
    </script>
  </body>
</html>

CSS

  • a {
      
        border-bottom: 2px solid blue;
    
    }
a {
  
    border-bottom: 2px solid blue;

}
selector
property
value
  • @media (prefers-color-scheme: dark) {
      body { background: black; }
    	
      h1, h2, h3 {
    	color: #fff;	  
      }
    }
@media (prefers-color-scheme: dark) {
  body { background: black; }
	
  h1, h2, h3 {
	color: #fff;	  
  }
}
media queries

Where do we put it?

1. INLINE

  • <p style="font-weight: bold"> 
        A simple styled paragraph...
    </p>
<p style="font-weight: bold"> 
    A simple styled paragraph...
</p>

2. <style> tag

  • <style> 
        h1 {
            text-align: center;
        }
    </style>
<style> 
    h1 {
        text-align: center;
    }
</style>

3. External

  • <!-- index.html -->
    
    <link rel="stylesheet" href="style.css" />
    
    <!-- style.css -->
    
    footer {
        color: #000;
        background-color: #fff;
    }
<!-- index.html -->

<link rel="stylesheet" href="style.css" />

<!-- style.css -->

footer {
    color: #000;
    background-color: #fff;
}

PRO & CONS to all of the above?

  • <img class="image round-image" id="profile" 
        src="user.jpg" />
    
    <style>
        img {
            border: 1px solid black;
        }
        
        .round-image {
            border: 5px dotted yellow;
        }
        .image {
            border: 10px dotted red;
        }
       
        #profile {
            border: 2px solid blue;
    }
    </style>
<img class="image round-image" id="profile" 
    src="user.jpg" />

<style>
    img {
        border: 1px solid black;
    }
    
    .round-image {
        border: 5px dotted yellow;
    }
    .image {
        border: 10px dotted red;
    }
   
    #profile {
        border: 2px solid blue;
}
</style>

selectors #2

& rule

parentΒ  rule

  • .valentines.in-love {
        // both "valentines" & "in-love" 
        //      classes
        text-decoration: make-up;
    }
.valentines.in-love {
    // both "valentines" & "in-love" 
    //      classes
    text-decoration: make-up;
}
  • .raining .human {
        /* "human" class elements inside a 
           "raining"-class element
        */
        display: hidden; 
        position: under-blanket;
    }
.raining .human {
    /* "human" class elements inside a 
       "raining"-class element
    */
    display: hidden; 
    position: under-blanket;
}
  • .raining.valentines .in-love {
        color: red;
    }
.raining.valentines .in-love {
    color: red;
}
  • faculty.in-iasi.state-owned .b4 #gicu {
        display: none;
    }
faculty.in-iasi.state-owned .b4 #gicu {
    display: none;
}

BRowser devtoosl

πŸ”— In-depth reading

THANK'S πŸ™

PS: check DevDrive over the weekend for practice exercises

CSS

Week #2
  • validate your HTML
  • meta tag
  • buttonsssss
  • modal: no fixed widths for the modal
  • before & after pseudo elements
  • no bonus points so why bother copying the solution?

Exercise take'aways

  • <style>
    
    .red {
        color: red;
    }
    
    .blue {
        color: blue;
    }
    
    </style>
    
    <p class="red blue"> Bob </p>
    <p class="blue red"> Alice </p>
    
<style>

.red {
    color: red;
}

.blue {
    color: blue;
}

</style>

<p class="red blue"> Bob </p>
<p class="blue red"> Alice </p>

writing css without going mad!

I'm using a mix of tag-based styling (whenever possible) plus BEM but without the modifiers part. For those I just go for the `is--{modifier}` syntax.

❗ Alwasy give the page and `block` element a unique class.

.not-found-page {
    text-align: center;
    h1 {
        margin-top: 0;
        font-size: calc(30px + 2vw);
    }

    h2 {
        font-weight: normal;
        font-size: calc(18px + 1.5vw);
        line-height: 2em;
    }
    button {
        margin-top: 1em;
        font-size: 20px;
    }
}

Blocks

Elements that bring meaning on their own!

Elements

Elements that have meaning only as part of a block.

.block { /** ... */ }
.block__element { /** ... */ }

modifier

A particular state of a block or element

.block__element--modifier { /** ... */ }
.topic-item {
    overflow: hidden;
    position: relative;
    border-radius: 0.5em;
    background: darken(color(black), 5%);
    border: 1px solid darken(color(grey), 10%);

    &.is--editing {
        padding: 0.5em 0.75em;
    }
 
    &.is--menu-open {
      .menu {
        display: block;
      }

      .menu-btn {
        text-align: center;
      }
    }
  
    &__name {
          display: inline-block;
          color: color(white);
          margin: 0.25em 0;
          font-size: 1.2em;
      }

    &__number {
      display: block;
      text-align: right;
      color: color(white);
    
    }
}

πŸ’ͺ Flexible, grid-based layout

🍧 Media queries

🎨 images that resize

Modern responsive design

media queries

@media screen and (max-width: 450px) {
  /* ... */
}

@media screen and (orientation: portrait) {
  /* ... */
}

@media (prefers-color-scheme: dark) { 
  /** ... */
}

images that resize

1 - Server-side solution
give me `cover.jpg`
seems like you're on mobile
sending `cover_small.jpg`
<picture>
  <source 
    srcset="image_high.jpg" 
    media="(min-width: 800px)">

  <source 
    srcset="image_low.jpg" 
    media="(min-width: 450px) and (max-width: 800px)">
  <img src="image_very_low.jpg" alt="image">
</picture>
2 - Client side solution
@media screen and (min-width: 800px) {
  .cover {
    background: url('cover_high.jpg');
  }
}

@media screen and (max-width: 800px) {
  .cover {
    background: url('cover_low.jpg');
  }
}

Flexible layout

❀ Flex

❀❀ Grid

From my experience, Flex is in many cases enough. However, I believe it soon won't be...

Implement Unsplash's 3-column gallery using Flex or Grid!

πŸ”΄

πŸ”΄

.5 sec
#logo {
  transition: transform .5s ease-in;
}

#logo:hover {
  transform: scale(1.1);
}
property
timing
function
duration

Transitions

or

animations

πŸ”΄

πŸ”΄

A
A

πŸ”΄

A

πŸ”΄

A
#logo {
  animation: rotate 1s linear infinite;
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }

  50% {
    transform: rotate(180deg);
  }

  100% {
    transform: rotate(360deg)
  }
}
duration
name
timing
function
iteration count

use a skeleton screen while the image loads

add a black-theme to everything you've coded so far!

Bonus
@media (prefers-color-scheme: dark) { 
  /** ... */
}
PS: you might need to use this πŸ‘‡
CSS in modern times
  • .topic-item {
        overflow: hidden;
        position: relative;
        /* ... */
                                 
        &__name {
          display: inline-block;
          margin: 0.25em 0;
          font-size: 1.2em;
        }
    
        &__number {
          /* ... */
        }
    }
    
    @for $i from 1 through 3 {
      .slider.displaying-#{$i} .content {
        @media (max-width: 640px) {
          transform: translateX(-$i * 100 + %);
        }
        @media (min-width: 641px) {
          transform: translateY(-$i * 100 + %);
        }
      }
    }
.topic-item {
    overflow: hidden;
    position: relative;
    /* ... */
                             
    &__name {
      display: inline-block;
      margin: 0.25em 0;
      font-size: 1.2em;
    }

    &__number {
      /* ... */
    }
}

@for $i from 1 through 3 {
  .slider.displaying-#{$i} .content {
    @media (max-width: 640px) {
      transform: translateX(-$i * 100 + %);
    }
    @media (min-width: 641px) {
      transform: translateY(-$i * 100 + %);
    }
  }
}
  • import React from 'react';
    
    import './Topic.style.scss';
    
    function TopicComponent() {
      return (<div> /* ... */ </div>);
    }
    
    export default TopicComponent;
import React from 'react';

import './Topic.style.scss';

function TopicComponent() {
  return (<div> /* ... */ </div>);
}

export default TopicComponent;
Bonus

CSS

Modules

  • import React from 'react';
    
    import styles from './Topic.style.scss';
    
    function TopicComponent() {
      return (<div className={style.topic}> /* ... */ </div>);
    }
    
    export default TopicComponent;
import React from 'react';

import styles from './Topic.style.scss';

function TopicComponent() {
  return (<div className={style.topic}> /* ... */ </div>);
}

export default TopicComponent;
  • /* Topic.style.scss */
    
    .topic {
      /* ... */
    }
/* Topic.style.scss */

.topic {
  /* ... */
}
  • <div class="topic_x21as"> 
      <!-- -->
    </div>
<div class="topic_x21as"> 
  <!-- -->
</div>

CSS in JS

  • import React from 'react';
    import styled from 'styled-components';
    
    const Link = styled.a`
      display: inline-block;
      border-radius: 3px;
      border: 2px solid white;
      ${props => props.primary && css`
        background: white;
        color: palevioletred;
       `}
    `
    
    function LinkComponent() {
      return ( <div>
        <Link
          href="https://github.com/styled-components/styled-components"
          target="_blank"
          rel="noopener"
          primary
        >
          GitHub
        </Link>
      </div>)
    }
    
import React from 'react';
import styled from 'styled-components';

const Link = styled.a`
  display: inline-block;
  border-radius: 3px;
  border: 2px solid white;
  ${props => props.primary && css`
    background: white;
    color: palevioletred;
   `}
`

function LinkComponent() {
  return ( <div>
    <Link
      href="https://github.com/styled-components/styled-components"
      target="_blank"
      rel="noopener"
      primary
    >
      GitHub
    </Link>
  </div>)
}

This being said, how do we approach the CSS of a project? πŸ€”

[discussions]

THANK'S πŸ™

PS: check DevDrive over the weekend for practice exercises

JAVASCRIPT

Week #3
βœ… it's single threaded
βœ… it's a dynamic language 
βœ… it's an open language, actively developed by TC39
βœ… everything in the same global scope
βœ… naming convention is usually camelCase
Brendan
Eich

created by ➑

JS Versions

officially called ecmascript

ES5
ES6
ES10
...
πŸ”— compat table

Objects

let myBake = {
  mark: "unknown",
  year: 2015,
  boughtFrom: {
    name: "Decathlon",
    address: "Era Shopping Park"
  }
}  
// Get properties
console.log(myBike.boughtAt.name);
console.log(myBike["boughtAt"]["name"]);

// Add properties
myBike.suspension = "full";

Arrays

// Object creation
let veryRandomList = [
    2, null, undefined, "bob", 
    [1, 2, 3] 
];

console.log(veryRandomList[3]);
// Arrays are Objects too
veryRandomList.name = "My List";

console.log(veryRandomList);

Functions

function sum(x,y) { 
  return x + y; 
}

let anotherVariable = function (x,y) { 
  return x - y; 
}

let letsBeFancy = (x,y) => x * y;

βœ” can be named or anonymous

βœ” doesn't brake if missing params. It's a dynamic lang πŸ˜…

βœ” if no explicit return, it implicitly returns undefined

βœ” are first class citizens - whatever you can do with the other variables you can do with functions

  • returned from functions
  • passed to functions as arguments
  • stored in variables

Functions

Scope

Where can we access the declared variables ❓
var name = "Bob";

printName();

function printName() {
  console.log(name);
}
βœ… The JS engine doesn't find that variable in the printName function so starts searching for it upstairs.

Β 

Think of an elevator. If you can't find what you're looking for on that floor, you go up and search there. And so on...
createPerson();
printName();

function createPerson() {
    let name = "Bob";
}

function printName() {
    console.log(name);
}
βœ… every function creates a new scope [function scope]

❌ you can't search in sibling scopes

var πŸ₯ŠΒ  let

  function scope   vs   block scope
since forever 
in JavaScript

πŸ‘‡

πŸ‘‡

available from ES6
goOut();

function goOut() {
    if (weather === "sunny") {
        let outfit = "light & casual";
    } else {
        let outfit = "light & casual + umbrella";
    }
    
    console.log(outfit);
}
❌ a block scoped variable is only available inside it's closest curly brackets { }

let || varΒ  πŸ₯ŠΒ  const

can be reassigned

πŸ‘‡

πŸ‘‡

cannot be reassigned
function goOut() {
    const outfit;
    if (weather === "sunny") {
        outfit = "light & casual";
    } else {
        outfit = "light & casual + umbrella";
    }
    
    console.log(outfit);
}
❌
❌
const person = {
    name: 'Bob',
    occupation: 'JavaScriptER',
    umbrella: true
};

if (weather === 'sunny') {
    person.umbrella = false;
}
βœ…
🎹 F12 or Cmd + F12

_____ is man's best friend!

_________ is a JS developer'sΒ  best friend!

❓

Devtools are

startGame();

function startGame() {
    let players = [{
        name: "Alice",
        gold: 120.123,
        life: .75
    }, {
        name: "Bob",
        life: 1
    }];

    for(let i = 0; i< players.length; i++) {
      console.log(getChangeToWin(players[i]));
    }
}

function getChangeToWin(player) {
    return Number(player.gold.toFixed(1)) ** 2 * player.life;
}
Find the bug and fix the code

CLOSURES

⭐ The ability of a function to access lexical scope variables even when it is executed in a different context.
function simpleF(x) {
  return function() {
    return x;
  }
}

let get11 = simpleF(11);
get11();

Closure exercises on devdrive.io

Closures are the only way of having true private data in JavaScript.*

function counter() {
  let value = 0;
  
  return increase() {
    value++;
  }
}

The 'value' variable cannot be accessed directly, only through the 'increase' function.

module pattern

Create a standalone module with a Public API and a Private one.

let notificationModule = (function() {
    let notifications = {};

    return {
      subscribe(username, topic) {
        notifications[topic] = notifications[topic] || [];
        notifications[topic].push(username);
      },
      unsubscribe(username, topic) {
        let indexOf;
        if (
          notifications[topic] && 
          (indexOf = notifications[topic].indexOf(username)) >= 0
        ) {
            notifications[topic].splice(indexOf, 1);
        }
      }
    };
})();
❗ But, how do I access the public API from inside the module?
let module = (function() {
    let notifications = {};
  	let publicApi = {
      /** ... */
    }
    
    return publicApi;
  
    function somePrivateFunction() {
      /** can access publicApi */
    }
})();

revealing module pattern

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Internationalization module pattern</title>
    </head>
    <body data-lang="en">
        <h1 data-text="hello_there"></h1>
        <p data-text="intro_paragraph"></p>
        <p data-text="later_text"></p>
    </body>
    <script>
        let i18n = (function() {
            /** */
        })();

        i18n.registerLanguage('en', {
            hello_there: 'Hey there',
            intro_paragraph: 'Welcome to this exercise'
        });

        try {
            i18n.applyLanguage(document.querySelector('body').dataset.lang);
        } catch (err) {
            alert('unsupported language');
        }

        i18n.registerSentences('en', {
            later_text: 'Some later text'
        });
        i18n.refresh();
    </script>
</html>

Create an internationalization module and make it work for the code below.

ModulePattern seems great but I feels there's a "but" somewhere...

❌ don't use it for instances because all those functions will be declared again and again.

THANK'S πŸ™

PS: check DevDrive over the weekend for practice exercises

this or that?

Week #4
1) No need to declare another variable. We can use directly the param. Plus, don't use the same name for the inner function.
function addF(x) {
  let value = x;
  return function addF(y){
    return value + y;
  }
}
function addF(x) {
  return function innerAddF(y){
    return x + y;
  }
}
2) What if we skip var, let and const?
double(12);

function double(x) {
  xDouble = x * 2;
}
❗ The variable is declared globally! Big NO NO!
3) Difference between == and ===/ != and !==

DEMO

{
}

prototype

The prototype represents the collection of properties and methods that all instances of a certain type/class inherit.
All Array's have a sort function already defined by the language. 

We say that the sort function is on the 
 Array prototype.
⭐ We can add properties/methods
The prototype is an object meaning that...
⭐ And even delete them...

DEMO

{
}
Everything* inherits from Object.prototype so technically everything is an object πŸ€”
Object.prototype
Array.prototype
Function.prototype
String.prototype
Number.prototype
...
}

Constructor pattern

let myBike = new Bike("Buburuza");
myBike.ride();


function Bike() {
  this.name = name;
}

Bike.prototype.ride = function() {
  console.log(`I'm riding ${this.name} bike`);
}

class pattern

let myBike = new Bike("Buburuza");
myBike.ride();


class Bike {
  constructor(name) {
    this.name = name;
  }

  ride() {
    console.log(`I'm riding ${this.name} bike`);
  }
}

inheritance | constructor pattern

function Animal(name) {
  this.name = name;
}

Animal.prototype.sayHello = function() {
  console.log(`Hello! I am ${this.name}, your pet!`);
}

function Dog(name, favoriteFood) {
    Animal.call(this, name);
    this.favoriteFood = favoriteFood;
} 
    
Dog.prototype = Object.create(Animal.prototype);

Dog.prototype.bark = function() {
  console.log(`${this.name}: woof woff`);
}

inheritance | Class pattern

class Animal {
  constructor() {
    this.name = name;
  }

  sayHello() {
    console.log(`Hello, I am ${this.name}, your pet!`);
  }
}

class Dog extends Animal {
  constructor(name, favoriteFood) {
    super(name);
    
    this.favoriteFood = favoriteFood;
  }
  
  bark() {
    console.log(`${this.name}: woof woof!`);
  }
}

Static Class

import Http from './Http.service';
import AppConstants from '~/App.constants';

class ExerciseService {
  static getAll() {
    return Http.get(`${AppConstants.ENDPOINT}/exercises`)
        	   .then(resp => resp.json());
  }
  
  static getTopics(username, exerciseId) {
    return Http.get(`${AppConstants.ENDPOINT}/exercises/${username}/${exerciseId}/topics`)
               .then(resp => resp.json());
  }
  
  /** ... */
}

export default ExerciseService;

I use them mostly as API Services

more real'life classes usecases

{
}

This

Probably the most misunderstood thing in JavaScript πŸ‘Ώ
But actually, there are just 4 simple rules... 

πŸ‘‡

1) Implicit binding
  obj.sayHello();
let foo = {
  name: 'Foo',
  sayHello() {
    console.log(`Hi! My name is ${this.name}`);
  }
}

let bar = { name: 'Bar' }

bar.sayHello = foo.sayHello;

foo.sayHello();
bar.sayHello();
2) Explicit binding
  obj.sayHello.call(newThis);
  obj.sayHello.apply(newThis);
let foo = {
  name: 'Foo',
  sayHello() {
    console.log(`Hi! My name is ${this.name}`);
  }
}

let bar = { name: 'Bar' }

foo.sayHello();
foo.sayHello.apply(bar)
  obj.sayHello.bind(newThis);
let foo = { name: 'Foo' }
let bar = { name: 'Bar' }

function sayHello() {
  console.log(`Hello, my name is ${this.name}`);
}

foo.sayHello = sayHello.bind(bar);
foo.sayHello();
3) New keyword
function JavaScripter(name) {
  console.log(this);
  
  this.name = name;
  this.motto = 'JS Rulz!';
}

new JavaScripter('Bob');
4) Default rule
function sayHello() {
  console.log(`Hello, my name is ${this.name}`);
}

sayHello();

If none of the above applies, this = window. *

Or undefined in strict mode

What about priority?

window.name = 'Window';

let foo = {
  name: 'Foo',
  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

let bar = { name: 'Bar' }
let baz = { name: 'Baz' }

foo.sayHello.bind(bar).bind(baz).call(foo);
⭐ Arrow functions
Borrows this from their enclosing scope.
class Dog {
  constructor(name) {
    this.name = name;
  }
  
  bark() {
    console.log(`${this.name}: woof woof!`);
  }
  
  delayBark(delay) {
    setTimeout(this.bark, delay);
  }
}

let dog = new Dog("Bob");
dog.delayBark(1000);
class Dog {
  constructor(name) {
    this.name = name;
  }
  
  bark() {
    console.log(`${this.name}: woof woof!`);
  }
  
  delayBark(delay) {
    setTimeout(() => {
      this.bark();
    }, delay);
  }
}

let dog = new Dog("Bob");
dog.delayBark(1000);

prototypes & "this" exercises on devdrive.io

THANK'S πŸ™

PS: check DevDrive over the weekend for practice exercises

classesΒ 

&

Callbacks

Week #5
1) The constructor property is not a good way of checking an objects type.
class MySpecialArray extends Array { }

let x = new MySpecialArray(1,2,3);

if(x.constructor === Array) {
  console.log("As expected...");  
} else {
  console.log("...or not");
}
if(x.prototype.isPrototypeOf(Array.prototype)) {
  console.log("Better...");  
}

if(Array.isArray(x)) {
  console.log("Much much better...");  
} 

Can you solve this JavaScript problem?

function PiggyBank(){
  let money = [];
  return {
    store: function(index, value){
      money[index] = value;
    },
    push: function(value){
      money.push(value);
    }
  }
}

let sharedPiggyBank = PiggyBank();

// Mom gives the sharedPiggyBank to Bob & Alice
// But, there's a weakness in this code which allows direct access to the money Array.
// Can you spot it?

Classes exercise from DevDrive.io

OR
class Tree {
    /** ... */
}

class TreeNode {
    /* ... */
}

const myTree = new Tree();
const rootNode = new TreeNode(22);

rootNode.putLeft(new TreeNode(11));
rootNode.putRight(new TreeNode(12));

rootNode.getLeft().putLeft(new TreeNode(10));
rootNode.getRight().putRight(13);


myTree.setRoot(rootNode);

myTree.print();  // 22 11 10 12 13

basics of async programming

setTimeout(function() {
  console.log('500ms have passed!');
}, 500)

[1,2,3].forEach((el) => {
  console.log(el);
})

setTimeout(function() {
  console.log('0ms have passed?');
}, 0)

console.log('before or after?');
document
    .getElementById('logo')
    .addEventListener('click', textBob);

function textBob() {
    console.log("On my way!");
}
A callback is a function invoked from another function which received it as a parameter.
setTimeout(textBob, 500);


document
    .getElementById("logo")
    .addEventEventListener("click", textBob);
callback
callback

Callbacks

Game engine

Hero Class

life decreases every second
interested 
class Hero(name, onUpdate) {
  constructor(onUpdate) {
    this.life = 100;
    
    setInterval(() => {
      this.life-= 10;
      
      onUpdate(this.life);
    }, 1000);
  }
}
let GameEngine = (function (){
  let newHero = new Hero(
        "Bob", 
        onHeroUpdate
    );

  function onHeroUpdate(data) {
      // do stuff
  }
}());

THANK'S πŸ™

PS: check DevDrive over the weekend for practice exercises

Week #6

node.js

package.json

Describes the project and all it's dependencies! Used both on the server (Node.js) and in modern client apps.

{
    "name": "imagemin-webp-webpack-plugin",
    "version": "3.2.2",
    "description": "Webpack plugin which converts images to the WebP format while also keeping the original files.",
    "author": {
        "name": "Alexandru Pavaloi",
        "email": "pava@iampava.com",
        "url": "https://iampava.com"
    },
    "license": "MIT",
    "main": "plugin.js",
    "keywords": [
        "webpack",
        "plugin",
        "webp",
        "imagemin",
        "images"
    ],
    "repository": "https://github.com/iampava/imagemin-webp-webpack-plugin.git",
    "bugs": "https://github.com/iampava/imagemin-webp-webpack-plugin/issues",
    "homepage": "https://github.com/iampava/imagemin-webp-webpack-plugin",
    "dependencies": {
        "imagemin": "^6.1.0",
        "imagemin-webp": "^5.1.0"
    }
}
#1 About
{
  "name": "imagemin-webp-webpack-plugin",
  "version": "3.2.2",
  "description": "Webpack plugin which converts images to the WebP format while also keeping the original files.",
  "author": {
    "name": "Alexandru Pavaloi",
    "email": "pava@iampava.com",
    "url": "https://iampava.com"
  },
  /* and much more */
}

Name, description, author, etc... Stuff you'd want to appear in NPM Registry. Here's an example package.

#2 Scripts

A set of command line instructions with a name so you can easily execute them.

{
  "name": "devdrive",
  "scripts": {
    "clear": "rm -rf dist/",
    "webpack": "webpack",
    "webpack-dev-server": "webpack-dev-server",
    "dev": "npm run webpack-dev-server -- --env.mode development --hot",
    "prod": "npm run clear && npm run webpack -- --env.mode production && node build-utils/add-template.js",
    "serve": "nodemon server.js --watch server --watch server.js"
    /* ... */
  }
}
#3 dependencies

3rd part packages that this projects needs in order to work in production.

{
  "name": "imagemin-webp-webpack-plugin",
  "version": "3.2.2",
  "dependencies": {
    "imagemin": "^6.1.0",
    "imagemin-webp": "^5.1.0"
  }
}
#4 devDependencies

3rd party packages that you need while developing and building this project for production. They are not actually used in the finished product.

{
  "name": "devdrive",
  "devDependencies": {
    "browserslist": "^4.7.0",
    "copy-webpack-plugin": "^5.0.4",
    "css-loader": "^3.2.0",
    "html-webpack-plugin": "^3.2.0",
    "imagemin-webp-webpack-plugin": "^3.2.1",
    /* ... */
  }
}
$ npm init

To initialize a new package.json

$ npm install

Installs all dependencies in the package.json present in that folder.

$ npm install lodash

Install the latest version of a package and add it to dependencies or devDependencies.

$ npm install lodash --save-dev
$ npm install -g heroku

Install a package globally. Now you can access it from from anywhere in the PC.

$ npm update

Update all packages. Beware of breaking changes 😱

⭐ Add the  node_modules folder to .gitignore. No point in pushing dozens of MB's of dependencies on GIT

require

Before ES Modules the only way of adding scripts into your Web App was... well actually inserting them in HTML.

<script src="app.js"></script>
<script src="lodash.js"></script>
<script src="react.js"></script>

Well... Node.js has no HTML so it comes with a module system

// index.js
let ImageminWebpPlugin = require('imagemin-web-webpack-plugin');
  // ➑ importing from a node_modules package


let routing = require('./routing.js');
  // ➑ importing from a relative file, maybe one we defined


let { add, mul } = require('./math-operations.js');
  // ➑ importing just 2 functions
// routing.js
class RoutingClass { /*...*/ } 

let router = new RoutingClass(/**/);

module.exports = router;
// math-operations.js
module.exports = {
  PI: 3.14,
  add: (x, y) => x + y,
  diff: (x, y) => x - y,
  mul: (x,y) => x * y
}

Implement a simple HTTP server which serves files from that directory.

$ npm run serve
  • parse the incoming request and extract the filename
  • it it's anything other than GET, return a 400 status code together with a JSON message. Otherwise:
  • try reading that file
    • if it doesn't exist, show a 404 page with a useful message
    • it it does:
      • determine it's mime type based on extension
      • read it's content as binary and send it to the browser
Bonus

Implement a routing system to make developing the app easier:

class HTTPServer {
  /* ... */
}

let server = new HTTPServer(/** ... */);

server.get('/', (req, res) => {
  // only get requests on root arrive here
})

server.get('/user/:id', (req, res) => {
  let { id } = req.params; 
  	// ➑ automatically extract params from the URL
  
  // respond with some user data
})

server.get('*', (req, res) => {
  // all get requests not intercepted arrive here.
  // great place for showing a generic 404 message
});

our first node.js server

Live coding πŸ’ͺ

THANK'S πŸ™

PS: check DevDrive over the weekend for practice exercises

Week #7

adding it all together!

Let's build the same app in 3 different ways:

Node.js
only
Client
only
Client,
Server &
REST API
Node.js only

Keep all the logic and state on the server.

Reload the page after each action!

πŸ˜‹

Dumb

client

πŸŽ…

Fat server

http://localhost:8080
πŸ“ HTML markup
πŸ‘†
First Button 
click
is actually a Form POST submit
πŸ“ a new page
πŸͺ stores data in cookie
πŸ‘†
Button 
click
is actually a Form POST submit
reads cookie data
πŸ“ & πŸͺ
Client only

Keep all the logic and state on the client.

Modify DOM directly upon user actions

πŸŽ“

Smart

client

πŸͺ‘

Static server

Client, server & REST API

Keep all the logic and state on the server.

Modify DOM directly based on API responses.

πŸŽ“

Smart'ish

client

🏒

web service

http://localhost:8080
πŸ“ HTML markup
Button 
click
triggers a GET/POST request
πŸ“’ JSON data

Update DOM

Teams of 2

{

}

and let's get going!

THANK'S πŸ™

PS: good luck working on the projects!

Week #10

Canvas

Examples

Imagine a blank Canvas on which you can programmatically paint stuff!

What?

⭐ geometrical shapes
⭐ images
⭐ pixel by pixel!

Why?

Highly interactive and dynamic apps.
⭐ games
⭐ photo/video editors
⭐ custom visualizations
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Simple canvas</title>
</head>
<body>
    <canvas width="1280" height="720"></canvas>
    <script>
        let canvas = document.querySelector("canvas");
        let ctx = canvas.getContext("2d");

        ctx.beginPath();
        ctx.rect(10, 100, 50, 50);

        ctx.fill();
    </script>
</body>
</html>

how?

Draw some mountains, a sky and a sun!
Drawing a polygonal shape
Drawing a round shape
Just like movies and their fps, we paint the canvas many times a second which gives the illusion of movement.

animating our canvas

window.requestAnimationFrame(function onFrame() {
    /* ... */
});
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Animated canvas</title>
</head>
<body>
    <canvas style="border: 2px solid green" width="1280" height="720"></canvas>
    <script>
        let size = 2;
        let sign = 1;

        let canvas = document.querySelector('canvas');
        let ctx = canvas.getContext('2d');

        window.requestAnimationFrame(function onFrame() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            ctx.beginPath();
            ctx.rect(0, 0, size, size);
            ctx.fill();
        
            if(size < 0 || size > 50) {
            sign *= -1;
            }
        
            size+= sign;
        
            window.requestAnimationFrame(onFrame);
        });
    </script>
</body>
</html>
Let's animate the birds across the sky! πŸ“
Bonus: move them across the sky using keyboard inputs!

THANK'S πŸ™

Week #11

ROLES

Reversed

πŸ”„

Adrian Ursaciuc
Cristian Gatu

πŸ”— Web Components

Workers

{ ? }

What & how

⭐ Web workers

⭐ Shared workers

⭐ Service workers

{ πŸ‘©β€πŸ’» DEMO πŸ‘¨β€πŸ’» }

Web Workers exercise on DevDrive

City Manager exercise on DevDrive

THANK'S πŸ™

Week #11

some more html apis

George Bădiță

Workers

Run JavaScript code separately from the main thread.

Why?

Avoid huge computations on the main thread to keep the app responsive. Ideally at 60fps ❀

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Web Workers demo</title>
</head>
<body>
    <p></p>
    <script>
        const randomValues = [Math.random() * 1000, Math.random() * 1000];

        if (window.Worker) {
            let myWorker = new Worker("worker.js");

            myWorker.postMessage(randomValues);

            myWorker.addEventListener('message', (e) => {
                document.querySelector('p').innerHTML  = e.data;
            })
        } else {
            console.log("Oups, seems like this is a legacy browser!");
        }

    </script>
</body>
</html>
index.html
worker.js
self.addEventListener('message', (e) => {
    let { data } = e;
    
    postMessage(`The result is ${data[0] + data[1]}`);
})
{
  type: string,
  payload: any
}

A widely used structure for sending Worker events so that it's easy to understand!

Service

Workers

Server
Client
Service
Worker
 if ('serviceWorker' in navigator) {
   navigator.serviceWorker
     .register('service-worker.js')
     .then(reg => {
     console.log("Successfully registered!");
   })
     .catch(err => {
     console.error("Oups", err);
   });
 }
main.js
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Service Workers demo</title>
</head>
<body>
    <script src="main.js"></script>
</body>
</html>
// Empty for now
service-worker.js
example.com
πŸ“ index.html
πŸ“ style.css
πŸ“ ...
Server
πŸ“ index.html
πŸ“ style.css
πŸ“ ...

Works offline

service-worker.js
const filesToCache = ["/", "style.css"];

self.addEventListener("install", event => {
  event.waitUntil(
    new Promise((res, rej) => {
      caches
        .open("static-files")
        .then(cache => {
          return Promise.all(
            filesToCache.map(url =>
              fetch(url).then(resp => {
                cache.put(url, resp);
              })
            )
          ).then(res);
        })
        .catch(rej);
    })
  );
});

self.addEventListener("fetch", event => {
  event.respondWith(
    new Promise((res, rej) => {
      const clonedRequest = event.request.clone();

      return caches
        .match(event.request, {
          cacheName: "static-files"
        })
        .then(resp => resp || fetch(clonedRequest));
    })
  );
});

APP LIKE

<link rel="manifest" href="manifest.json" />
{
    "name": "Geek Alert",
    "short_name": "Geek Alert",
    "theme_color": "#4141ac",
    "background_color": "#b1fcf8",
    "display": "standalone",
    "orientation": "portrait",
    "scope": ".",
    "start_url": ".",
    "icons": [
      {
        "src": "icons/icon-72x72.png",
        "sizes": "72x72",
        "type": "image/png"
      },
      /* ... */
    ]
}

engaging

// All the code from before
// Plus ⬇

firebase.messaging().useServiceWorker(swRegistration);

Notification.requestPermission().then(permission => {
  if (permission === "granted") {
    messaging.getToken().then(token => {
      console.log(token);
    });
  }
});
main.js
service-worker.js
// All the code from before
// Plus ⬇

self.addEventListener("push", event => {
  const payload = event.data.json().data;

  event.waitUntil(
    self.registration.showNotification(payload.title, {
      body: payload.body
    })
  );
});

Web/Service WorkersΒ  exercises πŸ”¨

happy holidays! πŸŽ…

webpack

Week #12

feedback discussion

Stop doing

Start doing

  • Giving many exs in a lab that most of us are unable to finish

  • Talking/teaching so fast

  • Student presentations shouldn’t last the whole class

  • Explain even if people say they understood
  • Add exercises on the platform sooner + solutions to them
  • Dedicate more time to those at the beginning than those more advanced
  • Dedicate more time to teaching best JS practices and ins and outs (instead of drawing a line on a canvas)
  • 5-10 mins about what’s new in the Web domain

webpack

[...] static module bundler for modern JavaScript applications. - Official Docs

why?

⭐ optimize your code and 3rd party one for release

⭐ use non-native Web technologies in your projects

⭐ seamlessly use more advanced techniques

⭐ pretty much anything through it's loaders/plugins system

minification
dead-code elimination
Typescript
SASS
lazy-loading

how? πŸ’ͺ

πŸ‘¨β€πŸ­ Work on your project and as me questions, maybe I can help πŸ‘©β€πŸ­

THANK'S πŸ™

recap

Final Week
πŸ“ƒ Timetable (soon)

WHAT NOW?

<br />

&

Project presentations

That's all folks!

STAW | Laboratories 2019

By Pava

STAW | Laboratories 2019

Slides for the STAW (Full Stack Web Development) I teach at the local Computer Science faculty. More info on https://iampava.com/staw

  • 1,397
Loading comments...

More from Pava