diceline-chartmagnifierquestion-marktwitter-whiteTwitter_Logo_Blue

Today I Learned

macOS asks for a PIN instead of a password

Whenever you try to athenticate macOS asks for a PIN instead of a password. This happens if you paired your key at some point with macOS.

Just open Terminal.app and unpair it:

sudo /usr/sbin/sc_auth unpair -u YourUserName

or simply

sudo /usr/sbin/sc_auth unpair

Take out your key if you have it plugged in and reboot.

Your key should be unpaired from your username. Remember you don't have to pair your key to use it. You only have to pair it if you want to use it for macOS authentication.

Regex simplicity vs normal

There are some cases when making use of regular expressions (regex) can exempt a lot of fuss from a programmers head. For example, let's compare the complexity between traditional logic and regex, in a function that excludes the vowels from a given string:

Traditional way:

function removeVowel(str) {
  let strList = str.split('');
  for (let i = 0; i < str.length; i++) {
    let char = str[i].toLowerCase();
    if (char == "a" || char == "e" || char == "i" || char == "o" || char == "u") {
      strList[i] = '';
    }
  }
  return strList.join('');
}

Regex Way:

function removeVowel(str){
  return str.replace( /[aeiou]/ig, '')
}

Temporarily render empty container until image is loaded to the screen

If we have a component that contains an image or video, we may face the case in which the component takes a different size from the one that is expected in the loading phase. This is because, while the image is loading, the size of the image is unknown, therefore the component will not render the image initially. This topic will throw a lot of issues and it can affect the user experience in a negative way, because components may take unnatural shapes while in the loading process.

This problem can be overcome by temporarily rendering:

  • an empty container with the estimated photo dimensions
  • a low resolution preview of the photo
  • a default blurred image that will show the user what to expect from the UI

In the case we want to temporarily render a empty div to the screen, we may need to mimic a responsive feel to the box, therefore "calc()" CSS function may come in handy:

.empty-div {
     background-color: transparent;
     background-size: 100% auto;
     width: calc(100vw - 100px);
     height: calc((100vw - 100px) * 0.46); /* decimal = height aspect ratio */
}

Add event listener on page resize

There is a special event listener in javascript that is called whenever a page resize is detected. The event listener is named 'resize' and can be used in the following way:

function onFrameResize(){
  console.table(
    {
      Height: window.innerHeight,
      Width: window.innerWidth  
    }
  );
}

window.addEventListener("resize", onFrameResize);

"window.innerHeight" and "window.innerWidth" are functions to access the width and the height of the frame.

This functionality will come in handy when working with responsive components.

Call function when image is loaded in VueJS using @load.

In VueJS, there is a way to find out when an image is fully loaded on a web page (when the image request is finished). We achieve this using the @load event that is available in VueJS and works in the following way:

<template>
  <div>
    <img 
      class="img__class"
      src="/photo.jpg"
      @load="onImageLoad"
     />
  </div>
</template>

export default {
  data: {
    isImageLoaded: false,
  },

  methods: {
    onImageLoad() {
      this.isImageLoaded = true
      // optional
      // console.log('Image is loaded')
    }
  }
}

This feature will come in handy if we want to render skeleton components while images are loading or if we want to implement lazy loading functionality.

How to use Makefiles to boost command-line productivity

Makefiles are an awesome tool which can help you become more productive command-line wise by encapsulating long commands and/or sequences of commands. They also help abstract away complexity.

One practical example of creating a make command would be setting up a Laravel project. All you need to do is create a file called Makefile and type in the following.

.PHONY setup
setup: # Setup project
    composer install
    php artisan migrate:fresh --seed
    npm install
    ...

Now, a new developer who needs to setup his/her project can skip writing down that series of commands by simply typing in the following:

make setup

But this doesn't end here. You can create virtually any command to help you automate certain processes such as creating or deleting files, changing permissions etc.

How to use factories to create relationships which follow a sequence

Factories an extremely useful tool for testing. The more complex the use case, the more awesome you find out Laravel factories are.

For instance, we might need to create a few items, each one with a different measurement of its own:

 Item::factory()
    //...
    ->has(Measurement::factory()->state(new Sequence(
        ['length' => 50, "width" => 110],
        ['length' => 65, "width" => 200],
        ['length' => 190, "width" => 295],
    )))
  ->count(3)
  ->create()

This will result in 3 items, each item having one unique measurement assigned. The first item will have a measurement with values corresponding to the first array in the sequence and so on.

JavaScript reduce function performance enhancement

Time complexity of implemented algorithms is an aspect which for sure should be taken into consideration when working on websites with big amounts of data. In this manner, let us test out the performance of the mother and father of all JavaScripts higher order functions - Array.prototype.reduce.

Problem description: Our API provides us with an array of objects that looks something like:

const objects = [
   { id: 1, name: "name 1"},
   { id: 2, name: "name 2"},
   { id: 3, name: "name 3"},
]

and we want to create a lookup table out of it, like this:

{
   1: "name 1",
   2: "name 2",
   3: "name 3",
}

using reduce:

const lookup = objects.reduce((lookup, object) => ({
     ...lookup,
     [object.id]: object.name
}), {})

It works, but the time complexity of this algorithm is (unexpectedly) O(n^3), because of the internal calls of Object.assign() that needs to copy bigger and bigger objects from iteration to iteration.

This is what JavaScript does internally:

objects.reduce((lookup, object) => Object.assign(
            Object.assign(lookup, {}), 
            { [object.id]: object.name }
        ), 
    {}
);

Time taken:

    100 records: ~0.08ms
  1.000 records: ~1.45ms
 10.000 records: ~  18ms
100.000 records: ~2600ms
1 mill  records: ~breaks

Performance boost:

const lookup = objects.reduce((lookup, object) => {
    lookup[object.id] = object.name
    return lookup
}, {})

Time taken:

    100 records: ~0.045ms
  1.000 records: ~ 0.15ms
 10.000 records: ~  1.5ms
100.000 records: ~  3.2ms
1 mill  records: ~   20ms

Great performance improvement by avoiding Object.assign calls and new object creation in each iteration.

TypeScripts Writable Computed Refs

Writable Computed Refs can be of real help when using Vue's Composition API along with TypeScript. Let's see what they are and how we can use them by getting through an example.

Problem description: let's assume we have to display a dialog with all our online users, if there are any. At the same time, we have the option to disable dialogs on our website, for some reason. In order achieve our goals, we are using an UI library like PrimeVue, Ant or Vuetify. These assist us with a reusable Dialog component that is visible when a boolean allows it to do so, something like this:

<Dialog 
   v-model:visible="isDialogVisible"
>

The problem that we encounter is that of declaring our isDialogVisible reactive variable. What are the problems you may think.

  1. It should both take into consideration if we have something to display in our list (if we have users in our store - using a getter for that) AND if we are allowed to display dialogs on our website. So it cannot be a simple reactive reference.

  2. You may think: alright, it's not really a problem, that's what computed properties are for. They are reactive and build up a value based on one or more raw variables. So this should solve the problem:

const isModalVisible = computed(() => useStore().getters.getOnlineUsers.length > 0 && areModalsAllowed.value);

Theoretically that's right, but it does not really solve our specific problem, because our dialog must also be closed in 3 scenarios (that means our isDialogVisible variable should be set to false): a. when dialogs are disabled on the website b. when we click on of the dialog's close button c. when the getter returns an empty list of users

The problem is that computed properties are not overridable. Depending on how you do it you could get one of the following warnings that cause unexpected behaviour and make the application not respond to the users commands of closing the dialog:

[Vue warn]: Computed property was assigned to but it has no setter.
[Vue warn]: Write operation failed: computed value is readonly.

Of course, it's a bad idea to empty the users list in the store and make the dialogs disabled on the website when you click on the close button, or to disable the dialogs on the website when there are no users in the store, or... you got the idea.

Here's where our Writable Computed Refs come into play and help us gracefully solve our problem:

const isDialogVisible: WritableComputedRef<boolean> = computed({
      get: (): boolean => useStore().getters.getOnlineUsers.length > 0 && areModalsAllowed.value,
      set: (newValue: boolean): void => { areModalsAllowed.value = newValue }
    });

Explanation: We can specifically state the generic WritableComputedRef type and construct our isDialogVisible boolean by providing an object with specific get and set methods to computed().
Our set method will be automatically used by the Dialog component when having to close the dialog due to the "Disable dialogs" button's click event. But when one checks for its value, our provided get method will also take the getters value into consideration.

We can understand this as surrounding(proxying) our computed property with custom get and set methods while it stays reactive.