/ Gists / JavaScript

Gists - JavaScript

On gists

HTML 5: Restricted datalist

JavaScript HTML

index.html #

<!DOCTYPE html>
<html lang="cs">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Výběr s Datalist</title>
  <script>
    function validateInput(input) {
      const datalist = document.getElementById('fruit-list');
      const options = datalist.getElementsByTagName('option');
      const values = Array.from(options).map(option => option.value);

      if (!values.includes(input.value)) {
        input.value = ''; // Vymaže hodnotu, pokud není v datalistu
      }
    }
  </script>
</head>
<body>
  <form>
    <label for="fruit">Vyberte ovoce:</label>
    <input type="text" id="fruit" name="fruit" list="fruit-list" oninput="validateInput(this)">
    <datalist id="fruit-list">
      <option value="Jablko">
      <option value="Banán">
      <option value="Třešně">
      <option value="Datle">
    </datalist>
    <button type="submit">Odeslat</button>
  </form>
</body>
</html>

On gists

Pipeline operator

JavaScript

index.js #

/* https://medium.com/@asierr/javascripts-pipeline-operator-the-game-changer-for-cleaner-code-e9eb46179510 */

const first = (x) => x + 1 
const second = (x) => x + 2 
const last = (x) => x + 1000 


const x = 0

const result = first(second(last(x)))
const result2 = x |> increment |> square |> double;


console.log(result)
console.log(result2)



/* examples */

// before
fetch('/api/data')
  .then(response => response.json())
  .then(data => transformData(data))
  .then(filteredData => display(filteredData));

// after
fetch('/api/data')
  .then(response => response.json())
  |> transformData
  |> display;


// after with await
const data = await fetchData() |> parseData |> processData


// before
const slug = replaceSpaces(toLowerCase(trim(userInput)));

// after
const slug = userInput |> trim |> toLowerCase |> replaceSpaces;

On gists

Composed Path

JavaScript

index.js #

document.querySelector('button').addEventListener('click', (e) => {
  console.log(e.composedPath())
})

On gists

Regexp - "v" modifier multilang chars

JavaScript

regex.js #

const nameRegex = /^\p{Letter}+$/v;

function validateName(name) {
  if (nameRegex.test(name)) {
    console.log(`${name} is a valid name.`);
  } else {
    console.log(`${name} contains invalid characters.`);
  }
}

validateName("John"); // "John is a valid name."
validateName("María"); // "María is a valid name."
validateName("佐藤"); // "佐藤 is a valid name."
validateName("John123"); // "John123 contains invalid characters."

On gists

Usefull detach handler

JavaScript

detach.js #

/*
https://javascript.plainenglish.io/7-infamous-javascript-bugs-that-shook-the-internet-3cf8f8f76098
*/

// Proper event listener cleanup to prevent memory leaks
function attachEvent() {
  const btn = document.querySelector("#myButton");
  const handleClick = () => console.log("Button clicked!");
  btn.addEventListener("click", handleClick);

  // Return a function to remove the listener and free up memory
  return () => btn.removeEventListener("click", handleClick);
}
const detach = attachEvent();
detach(); // Cleanup resources

On gists

Img.decode() // nahrada za onload()

JavaScript

img-decode.js #

const img = document.querySelector('img')
const tempImg = new Image()

tempImg.src = 'https://masoprofit.cz/storage/images/1600x2000/41847.png.webp'

tempImg.decode().then(() => {
  img.src = tempImg.src
}).catch(e => {
  console.log(e)
})

On gists

Promise.all

JavaScript

examples.js #

// Parallel
async function getData() {
    const [user, posts] = await Promise.all([
        fetchUserData(),
        fetchPostsData()
    ]);
    console.log(user, posts);
}


// non parallel
function getData() {
    return Promise.all([fetchUser(), fetchPosts()])
        .then(([user, posts]) => {
            console.log(user, posts);
        })
        .catch((error) => {
            console.error(error); 
        });
}

On gists

Do you know JS array methods?

JavaScript

data.js #

const employees = [
    {
        id: 1,
        first_name: 'Jan',
        lastname: 'Novák',
        age: 45,
        salary: 85000,
        role: 'CEO',
    },
    {
        id: 2,
        first_name: 'Marie',
        lastname: 'Svobodová',
        age: 32,
        salary: 45000,
        role: 'Developer',
    },
    {
        id: 3,
        first_name: 'Petr',
        lastname: 'Dvořák',
        age: 28,
        salary: 65000,
        role: 'Developer',
    },
    {
        id: 4,
        first_name: 'Lucie',
        lastname: 'Černá',
        age: 24,
        salary: 35000,
        role: 'Developer',
    },
    {
        id: 5,
        first_name: 'Tomáš',
        lastname: 'Procházka',
        age: 38,
        salary: 55000,
        role: 'Manager',
    },
    {
        id: 6,
        first_name: 'Eva',
        lastname: 'Marková',
        age: 29,
        salary: 42000,
        role: 'Designer',
    },
    {
        id: 7,
        first_name: 'Martin',
        lastname: 'Kučera',
        age: 35,
        salary: 48000,
        role: 'Manager',
    },
    {
        id: 8,
        first_name: 'Anna',
        lastname: 'Veselá',
        age: 26,
        salary: 35000,
        role: 'Support',
    },
    {
        id: 9,
        first_name: 'Jakub',
        lastname: 'Horák',
        age: 31,
        salary: 65000,
        role: 'Developer',
    },
    {
        id: 10,
        first_name: 'Tereza',
        lastname: 'Pokorná',
        age: 27,
        salary: 38000,
        role: 'Accountant',
    },
    {
        id: 11,
        first_name: 'David',
        lastname: 'Král',
        age: 33,
        salary: 45000,
        role: 'Developer',
    },
    {
        id: 12,
        first_name: 'Barbora',
        lastname: 'Němcová',
        age: 30,
        salary: 42000,
        role: 'Designer',
    },
    {
        id: 13,
        first_name: 'Milan',
        lastname: 'Urban',
        age: 42,
        salary: 55000,
        role: 'Manager',
    },
    {
        id: 14,
        first_name: 'Veronika',
        lastname: 'Machová',
        age: 25,
        salary: 38000,
        role: 'Designer',
    },
    {
        id: 15,
        first_name: 'Filip',
        lastname: 'Sedláček',
        age: 34,
        salary: 48000,
        role: 'Manager',
    },
    {
        id: 16,
        first_name: 'Kristýna',
        lastname: 'Vacková',
        age: 28,
        salary: 42000,
        role: 'HR',
    },
    {
        id: 17,
        first_name: 'Josef',
        lastname: 'Malý',
        age: 39,
        salary: 55000,
        role: 'Manager',
    },
    {
        id: 18,
        first_name: 'Kateřina',
        lastname: 'Šimková',
        age: 31,
        salary: 45000,
        role: 'Analyst',
    },
    {
        id: 19,
        first_name: 'Ondřej',
        lastname: 'Beneš',
        age: 36,
        salary: 65000,
        role: 'Developer',
    },
    {
        id: 20,
        first_name: 'Michaela',
        lastname: 'Fialová',
        age: 29,
        salary: 42000,
        role: 'Designer',
    },
    {
        id: 21,
        first_name: 'Pavel',
        lastname: 'Bartoš',
        age: 44,
        salary: 55000,
        role: 'Manager',
    },
    {
        id: 22,
        first_name: 'Lenka',
        lastname: 'Kolářová',
        age: 27,
        salary: 38000,
        role: 'Designer',
    },
    {
        id: 23,
        first_name: 'Roman',
        lastname: 'Kovář',
        age: 33,
        salary: 45000,
        role: 'Developer',
    },
    {
        id: 24,
        first_name: 'Martina',
        lastname: 'Říhová',
        age: 30,
        salary: 48000,
        role: 'Manager',
    },
    {
        id: 25,
        first_name: 'Lukáš',
        lastname: 'Vlček',
        age: 35,
        salary: 65000,
        role: 'Developer',
    },
    {
        id: 26,
        first_name: 'Adéla',
        lastname: 'Tichá',
        age: 26,
        salary: 35000,
        role: 'Support',
    },
    {
        id: 27,
        first_name: 'Vojtěch',
        lastname: 'Havel',
        age: 40,
        salary: 55000,
        role: 'Manager',
    },
    {
        id: 28,
        first_name: 'Simona',
        lastname: 'Hrubá',
        age: 32,
        salary: 45000,
        role: 'HR',
    },
    {
        id: 29,
        first_name: 'Robert',
        lastname: 'Krátký',
        age: 37,
        salary: 65000,
        role: 'Developer',
    },
    {
        id: 30,
        first_name: 'Monika',
        lastname: 'Zelená',
        age: 28,
        salary: 45000,
        role: 'Developer',
    },
    {
        id: 31,
        first_name: 'Karel',
        lastname: 'Marek',
        age: 41,
        salary: 48000,
        role: 'Analyst',
    },
    {
        id: 32,
        first_name: 'Petra',
        lastname: 'Vávrová',
        age: 29,
        salary: 42000,
        role: 'Support',
    },
    {
        id: 33,
        first_name: 'Adam',
        lastname: 'Řezáč',
        age: 34,
        salary: 65000,
        role: 'Developer',
    },
    {
        id: 34,
        first_name: 'Jana',
        lastname: 'Holubová',
        age: 31,
        salary: 42000,
        role: 'HR',
    },
    {
        id: 35,
        first_name: 'Miroslav',
        lastname: 'Jelínek',
        age: 43,
        salary: 55000,
        role: 'Manager',
    },
    {
        id: 36,
        first_name: 'Klára',
        lastname: 'Štěpánková',
        age: 27,
        salary: 38000,
        role: 'Support',
    },
    {
        id: 37,
        first_name: 'Daniel',
        lastname: 'Doležal',
        age: 36,
        salary: 65000,
        role: 'Developer',
    },
    {
        id: 38,
        first_name: 'Nikola',
        lastname: 'Urbanová',
        age: 30,
        salary: 42000,
        role: 'Designer',
    },
    {
        id: 39,
        first_name: 'Marek',
        lastname: 'Šťastný',
        age: 38,
        salary: 48000,
        role: 'Analyst',
    },
    {
        id: 40,
        first_name: 'Zuzana',
        lastname: 'Kadlecová',
        age: 29,
        salary: 35000,
        role: 'Support',
    },
    {
        id: 41,
        first_name: 'Jiří',
        lastname: 'Moravec',
        age: 45,
        salary: 55000,
        role: 'Manager',
    },
    {
        id: 42,
        first_name: 'Hana',
        lastname: 'Beranová',
        age: 33,
        salary: 45000,
        role: 'HR',
    },
    {
        id: 43,
        first_name: 'Michal',
        lastname: 'Růžička',
        age: 32,
        salary: 65000,
        role: 'Developer',
    },
    {
        id: 44,
        first_name: 'Andrea',
        lastname: 'Kopecká',
        age: 28,
        salary: 38000,
        role: 'Designer',
    },
    {
        id: 45,
        first_name: 'Radek',
        lastname: 'Bureš',
        age: 37,
        salary: 48000,
        role: 'Manager',
    },
    {
        id: 46,
        first_name: 'Denisa',
        lastname: 'Havlíčková',
        age: 26,
        salary: 35000,
        role: 'Support',
    },
    {
        id: 47,
        first_name: 'Patrik',
        lastname: 'Pospíšil',
        age: 34,
        salary: 45000,
        role: 'Developer',
    },
    {
        id: 48,
        first_name: 'Iveta',
        lastname: 'Kratochvílová',
        age: 31,
        salary: 42000,
        role: 'Designer',
    },
    {
        id: 49,
        first_name: 'Štěpán',
        lastname: 'Janda',
        age: 39,
        salary: 65000,
        role: 'Developer',
    },
    {
        id: 50,
        first_name: 'Gabriela',
        lastname: 'Součková',
        age: 30,
        salary: 42000,
        role: 'HR',
    },
];

On gists

WeakMap / WeakSet

JavaScript

examples.js #

// https://javascript.plainenglish.io/memory-magic-in-javascript-why-weakmaps-and-weaksets-are-your-secret-weapon-for-high-performance-62562cc24dc5

// 1. Private Data Storage Inside Classes
const privateData = new WeakMap();

class BankAccount {
  constructor(balance) {
    privateData.set(this, { balance });
  }

  getBalance() {
    return privateData.get(this).balance;
  }
}

// 2. Caching Expensive Computations
const cache = new WeakMap();
function compute(obj) {
  if (!cache.has(obj)) {
    cache.set(obj, expensiveCalculation(obj));
  }
  return cache.get(obj);
}


// 3. Avoiding Memory Leaks in DOM-based Apps
const elementData = new WeakMap();

function attachData(el, data) {
  elementData.set(el, data);
}

function getData(el) {
  return elementData.get(el);
}



// 1. Tracking Objects Without Overhead
const processedItems = new WeakSet();

function process(item) {
  if (processedItems.has(item)) return;
  // Process the item
  processedItems.add(item);
}

On gists

Optimize Complex Conditionals in JavaScript

JavaScript

index.js #

// https://blog.stackademic.com/how-to-optimize-complex-conditionals-in-javascript-0fcaf0add82a


const onButtonClick = (status) => {
  if (status == 1) {
    jumpTo('Index Page');
  } else if (status == 2 || status == 3) {
    jumpTo('Failure Page');
  } else if (status == 4) {
    jumpTo('Success Page');
  } else if (status == 5) {
    jumpTo('Cancel Page');
  } else {
    jumpTo('Other Actions');
  }
};

// 1
// if => switch

const onButtonClick = (status) => {
  switch (status) {
    case 1:
      jumpTo('Index Page');
      break;
    case 2:
    case 3:
      jumpTo('Failure Page');
      break;
    case 4:
      jumpTo('Success Page');
      break;
    case 5:
      jumpTo('Cancel Page');
      break;
    default:
      jumpTo('Other Actions');
  }
};


// ------------------------------------------


const onButtonClick = (status, identity) => {
  if (identity == 'guest') {
    if (status == 1) {
      // logic for guest status 1
    } else if (status == 2) {
      // logic for guest status 2
    }
    // Additional logic for other statuses...
  } else if (identity == 'master') {
    if (status == 1) {
      // logic for master status 1
    }
    // Additional logic for other statuses...
  }
};


// 2
// interesting solution ;)
// nested if to map with keys where key mean concaten ifs..

const actions = new Map([
  ['guest_1', () => { /* logic for guest status 1 */ }],
  ['guest_2', () => { /* logic for guest status 2 */ }],
  ['master_1', () => { /* logic for master status 1 */ }],
  ['master_2', () => { /* logic for master status 2 */ }],
  ['default', () => { /* default logic */ }],
]);

const onButtonClick = (identity, status) => {
  const action = actions.get(`${identity}_${status}`) || actions.get('default');
  action();
};




// 3
// object with keys instead of use of ifs
const actions = {
  '1': 'Index Page',
  '2': 'Failure Page',
  '3': 'Failure Page',
  '4': 'Success Page',
  '5': 'Cancel Page',
  'default': 'Other Actions',
};

const onButtonClick = (status) => {
  const action = actions[status] || actions['default'];
  jumpTo(action);
};