diceline-chartmagnifierquestion-marktwitter-whiteTwitter_Logo_Blue

Today I Learned

Conditionally add properties to objects in Javascript

This comes in handy when you want to completely omit a property from an object in case the value is undefined or null.

{prop1, prop2, ...(condition && prop3)}

The trick being here:

...(condition && prop3)

In case the condition evaluates to false, the property will be completely omitted from the object, otherwise, both the value and its corresponding key will show up in the end result.

Correctly grouping members within modules in JSDoc v3

JSDoc is great! It's documentation not so much. I needed a way to logically group together global methods and I was unsuccessful in finding a straightforward way in its official documentation.

Eventually, I've come across the following method, using @module and @member.

First, we define the module name, usually at the top of the file:

@module MyModule

We then proceed to annotate the target function with @memeber MyModule. One other important aspect is to also include @function along with the name of the function in order to appear in the module section.

/**
 * @member MyModule
 * @function myFunction
 ....
 */
 export const myFunction = () => ....

Using destructuring assignment to dynamically create new functions in JavaScript

// www.codewars.com/kata/525f3eda17c7cd9f9e000b39

const curry = (operand, operator) => (!operator) ? operand : operator(operand);

const [zero, one, two, three, four, five, six, seven, eight, nine] =
  [0,1,2,3,4,5,6,7,8,9].map(operand => ((operator) => curry(operand, operator)));

const plus = (first) => (second) => second + first;
const minus = (first) => (second) => second - first;
const times = (first) => (second) => second * first;
const dividedBy = (first) => (second) => Math.floor(second / first);

vue-cli-service environment variables

While you can find detailed information in the official docs, I dare to spoil the fun for you:

1. All app variables are pulled in if they are prefixed with VUE_APP_.

Example: VUE_APP_API_URL.

You can now access the variables in your application like this: process.env.APP_URL.

2. All e2e variables are fetched if they are prefixed withCYPRESS_.

Example: CYPRESS_APP_URL.

You can now access the variables in your tests like this: Cypress.env('APP_URL').

Make LiveView template variables readable

If you ever seen this in the wild:

{:ok, assign(socket,
      %{my_variable: @my_variable
        my_other_variable: nil.
        yet_another_variable: nil 
      })}

Remember that applying elixir's pipe operator makes everything better:

def mount(_session, socket) do
    socket =
      socket
      |> assign(:my_variable, @my_variable)
      |> assign(:my_other_variable, nil)
      |> assign(:yet_another_variable, nil)
    {:ok, socket}
end

LocalStorage event not triggering

Whenever a value is set in localStorage, a storage event will be dispatched on all other windows from the same origin. The event is not fired or catchable in the originator window when it is modified through a script.

This was a problem because I wanted to be able to have an Elm subscription as the only source of truth for my session.

In order to achieve this, I'm mimicking the storage event from within the command port as soon as the message is received through the port.

app.ports.commandPort.subscribe(session => {
  localStorage.session = JSON.stringify(session);
  app.ports.subscriptionPort.send(localStorage.session);
});
window.addEventListener(
    "storage",
    event => {
      if (event.storageArea === localStorage && event.key === "session") {
        app.ports.subscriptionPort.send(event.newValue);
      }
    },
    false
);

And in Elm:

port subscriptionPort : (Encode.Value -> msg) -> Sub msg
port commandPort : Maybe Encode.Value -> Cmd msg