/ Gists

Gists

On gists

Error Boundary aka Nuxt

Vue.js

ErrorBoundary.vue #

<!--ErrorBoundary.vue-->
<!-- https://vueschool.io/articles/vuejs-tutorials/what-is-a-vue-js-error-boundary-component/ -->
<script setup>
import { ref, computed } from 'vue'

// create an reactive container to store the potential error
const error = ref()

// using Vue's build in lifecycle hook
// listen for errors from components passed to the default slot
onErrorCaptured(err => {
  // set the reactive error container to the thrown error
  error.value = err

  // return false to prevent error from bubbling further
  // (this is optional, if you have a top level error reporter catching errors
  // you probably don't want to do this.
  // Alternatively you could report your errors in the boundary and prevent bubble
  return false
})

// create a way to clear the error
function clearError() {
  error.value = null
}

// provide the error and the clear error function to the slot
// for use in consuming component to display messaging
// and clear the error
const slotProps = computed(() => {
  if (!error.value) return {}
  return { error, clearError }
})

// if there's an error show the error slot, otherwise show the default slot
const slotName = computed(() => (error.value ? 'error' : 'default'))
</script>
<template>
  <slot :name="slotName" v-bind="slotProps"></slot>
</template>

On gists

Overlay on image with 1 line of code (border-image)

CSS trick

demo.css #

/* https://codepen.io/kevinpowell/pen/yLWNbdJ */

.overlay {
  border-image: linear-gradient(hsl(240 100% 20% / 0.6), hsl(0 100% 20% / 0.6))
    fill 1;
}

On gists

Ajax events on forms (Vue)

AW

vue-form-events.vue #

<template>
  <form
    class="mt-8"
    method="post"
    :id="frmId"
    v-ajax-on-before="() => $emit('onPreloader', true)"
    v-ajax-on-success="() => $emit('onPreloader', false)"
    v-ajax-on-error="() => $emit('onPreloader', false)"
    v-nette-form
    data-ajax-use-router
  >

On gists

vue-form-

vue-form- #

<template>
  <form
    class="mt-8"
    method="post"
    :id="frmId"
    v-ajax-on-before="() => $emit('onPreloader', true)"
    v-ajax-on-success="() => $emit('onPreloader', false)"
    v-ajax-on-error="() => $emit('onPreloader', false)"
    v-nette-form
    data-ajax-use-router
  >

On gists

5 Responsive Layouts (KP)

CSS CSS trick

code.css #

/* https://codepen.io/kevinpowell/full/vYvEdWG */


.cluster {
  outline: 5px solid hotpink;
  padding: 1rem;

  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

.flexible-grid {
  outline: 5px solid hotpink;
  padding: 1rem;

  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.flexible-grid > * {
  flex: 1;
}

.auto-grid {
  outline: 5px solid hotpink;
  padding: 1rem;

  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(10rem, 100%), 1fr));
}

.reel {
  outline: 5px solid hotpink;
  padding: 1rem;

  display: grid;
  gap: 1rem;
  grid-auto-flow: column;
  grid-auto-columns: 45%;
  overflow-x: scroll;
  scroll-snap-type: x mandatory;
  scroll-padding: 1rem;
}

.reel > * {
  scroll-snap-align: start;
}

.main-with-sidebar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 1em;
  max-width: 1200px;
  margin-inline: auto;
}

.main-with-sidebar > :first-child {
  flex-basis: 500px;
  flex-grow: 9999;
}
.main-with-sidebar > :last-child {
  flex-basis: 300px;
  flex-grow: 1;
}

On gists

Promises

JavaScript

promises.js #

// https://medium.com/@hxu0407/master-these-8-promise-concurrency-control-techniques-to-significantly-improve-performance-5a1c199b6b3c


// 1. Promise.all: Execute in Parallel and Return Results Together
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
  .then(results => {
    console.log(results); // Output: [1, 2, 3]
  });
  
  
  
  
// 2. Promise.allSettled: Execute in Parallel and Return All States
const promise1 = Promise.resolve(1);
const promise2 = Promise.reject("Error");
const promise3 = Promise.resolve(3);
Promise.allSettled([promise1, promise2, promise3])
  .then(results => {
    console.log(results);
    /* Output:
    [
      { status: 'fulfilled', value: 1 },
      { status: 'rejected', reason: 'Error' },
      { status: 'fulfilled', value: 3 }
    ]
    */
  })
  
  
  
  
// 3. Promise.race: Execute in Parallel and Return the Fastest
const promise1 = new Promise(resolve => setTimeout(() => resolve("Fast"), 100));
const promise2 = new Promise(resolve => setTimeout(() => resolve("Slow"), 500));
Promise.race([promise1, promise2])
  .then(result => console.log(result)); // Output: "Fast" (whichever resolves first)
  
  
  
  
// 4. Promise.any (ES2021): Execute in Parallel and Return the First Fulfilled
const promise1 = Promise.reject("Error 1");
const promise2 = new Promise(resolve => setTimeout(() => resolve("Success"), 200));
const promise3 = Promise.reject("Error 2");
Promise.any([promise1, promise2, promise3])
  .then(result => console.log(result)) // Output: "Success"
  .catch(error => console.log(error.errors)); // If all reject
  
  
  
  
// 5. Custom Concurrency Control Function: Limit Max Concurrent Requests
async function limitConcurrency(tasks, limit) {
  const results = [];
  const running = new Set();
  
  for (const task of tasks) {
    const promise = task().then(result => {
        running.delete(promise);
        return result;
    });
    running.add(promise);
        results.push(promise);
        if (running.size >= limit) {
          await Promise.race(running);
        }
      }
  return Promise.all(results);

On gists

9 Smart Ways to Replace if-else in JavaScript

Popular ⭐ JavaScript

ways.js #

// https://medium.com/@hxu0407/9-smart-ways-to-replace-if-else-in-javascript-28f82ad6dcb9

// 1. Object Mapping Instead of if-else
function getPrice(user) {
  if (user.type === 'vip') {
    return 'VIP Price';
  } else if (user.type === 'svip') {
    return 'SVIP Price';
  } else if (user.type === 'vvip') {
    return 'VVIP Price';
  } else {
    return 'Regular Price';
  }
}

// better
const priceStrategy = {
  vip: () => 'VIP Price',
  svip: () => 'SVIP Price',
  vvip: () => 'VVIP Price',
  default: () => 'Regular Price'
};

function getPrice(user) {
  return (priceStrategy[user.type] || priceStrategy.default)();
}



// 2. Replace Multiple Conditions with Array.includes
if (status === 'failed' || status === 'error' || status === 'rejected') {
  handleError();
}

// better
const errorStatus = ['failed', 'error', 'rejected'];
if (errorStatus.includes(status)) {
  handleError();
}



// 3. Chained Ternary Operators
let message;
if (score >= 90) {
  message = 'Excellent';
} else if (score >= 80) {
  message = 'Good';
} else if (score >= 60) {
  message = 'Pass';
} else {
  message = 'Fail';
}

// better 
const message =
  score >= 90 ? 'Excellent' :
  score >= 80 ? 'Good' :
  score >= 60 ? 'Pass' :
  'Fail';
  
  
  
// 4. Logical Operators && and ||
// Replacing a simple `if`
user.isAdmin && showAdminPanel();
// Setting default values
const name = user.name || 'unnamed';
// Nullish coalescing
const count = data?.users ?? [];



// 5. Switch-Case with Pattern Matching
const actions = new Map([
  [/^vip/, handleVip],
  [/^admin/, handleAdmin],
  [/^user/, handleUser]
]);

/*or

const actions = [
  [/^vip/, handleVip],
  [/^admin/, handleAdmin],
  [/^user/, handleUser]
];
*/

const handleRequest = (type) => {
  const action = [...actions].find(([key]) => key.test(type));
  return action ? action[1]() : handleDefault();
};



// 6. Using Proxy for Conditional Interception
const handler = {
  get: (target, property) => {
    return property in target ? target[property] : target.default;
  }
};

const services = new Proxy({
  admin: () => 'Admin Service',
  user: () => 'User Service',
  default: () => 'Default Service'
}, handler);



// 7. Functional Approach
// Composing conditions
const isAdult = age => age >= 18;
const hasPermission = role => ['admin', 'superuser'].includes(role);
const canAccess = user => isAdult(user.age) && hasPermission(user.role);

// Usage
users.filter(canAccess).forEach(grantAccess);



// 8. State Machine Pattern
const stateMachine = {
  draft: {
    publish: 'published',
    delete: 'deleted'
  },
  published: {
    unpublish: 'draft',
    archive: 'archived'
  },
  archived: {
    restore: 'draft'
  }
};

const changeState = (currentState, action) =>
  stateMachine[currentState]?.[action] || currentState;
  
  
  
// 9. Use Decorators to Handle Conditional Logic
function checkPermission(target, name, descriptor) {
  const original = descriptor.value;
  descriptor.value = function (...args) {
    if (this.user?.hasPermission) {
      return original.apply(this, args);
    }
    throw new Error('No permission');
  };
  return descriptor;
}

class Document {
  @checkPermission
  edit() {
    // Edit the document
  }
}


On gists

ways.js

ways.js #

// https://medium.com/@hxu0407/9-smart-ways-to-replace-if-else-in-javascript-28f82ad6dcb9

On gists

Vue advanced

Vue.js

advanced.js #

/*
onScopeDispose - Podobně jako onWatcherCleanup, ale obecnější. 
Zavolá se, když je aktuální reaktivní efektový scope (effect scope) ukončen. 
Je to užitečné pro čištění zdrojů v jakémkoliv reaktivním kontextu:
*/

// 1
import { onScopeDispose, effectScope } from 'vue'

// Vytvoření izolovaného scope
const scope = effectScope()

scope.run(() => {
  // Kód uvnitř scope
  
  onScopeDispose(() => {
    // Tento kód se zavolá při scope.stop()
  })
})

// Později můžete ukončit scope
scope.stop()




// 2) 
const scope = effectScope()

scope.run(() => {
  const state = reactive({ count: 0 })
  const double = computed(() => state.count * 2)
  watch(() => state.count, (count) => console.log(count))
})

// Později ukončí všechny reaktivní efekty
scope.stop()

On gists

Watch - advanced

Vue.js

watch.js #

// 1) cleanup when watch is ended
import { watch, onWatcherCleanup } from 'vue'

watch(id, (newId) => {
  const { response, cancel } = doAsyncWork(newId)
  // `cancel` is called if `id` changes or the component unmounts
  onWatcherCleanup(cancel)
})



// 2) better watch with desctruct
const { pause, resume, stop } = watch(source, (newVal, oldVal) => {
  // Watch logic
});

// Pause watching
pause();

// Resume watching
resume();




// 3 watch logic, not only true/false ...
watch(reactiveObject, (newVal, oldVal) => {
  // Watch logic
}, { deep: 2 });