When using arrays, you can add multiple conditions that must apply to the same element.

In the query db.items({list: {$elemMatch: {a: 1, b: "green"}}}), the condition is "a single array element of the list property must match a: 1 and b: "green"".

Read more

Nginx needs "execute" access to the directories where the files you want to serve live, and also to every parent directory, all the way to the top.

So, if you want to serve /home/me/my_site/index.html, and the Nginx's host configuration points to /home/me/my_site, make sure the www-data user (or whichever user Nginx is using) has this permission on /home, /home/me, and /home/me/my_site.

Read more

URL objects have both a search property that shows the query parameters as a single string and searchParams, a URLSearchParams object with which you can manage the params without having to think about URL encoding or any nastiness.

const myUrl = new URL("https://example.com/my-page?id=1&q=search%20term");

myUrl.search === "?id=1&q=search%20term"
myUrl.searchParams.get("q") === "search term"
myUrl.searchParams.set("q", "other search term");

// {id: '1', q: 'other search term'}
Read more

You can pass more than a single variable to PHP's isset(). From the docs:

If multiple parameters are supplied then isset() will return true only if all of the parameters are considered set. Evaluation goes from left to right and stops as soon as an unset variable is encountered.

Read more

You can define primitive type aliases (e.g. string identifiers) in TypeScript that prevent you from using the wrong type using unique symbols:

type userId = string & {readonly id: unique symbol};
type projectId = string & {readonly id: unique symbol};

// A string can't just be assigned as a userId anymore, but this works.
const myUserId: userId = "u001" as userId;

// TS2322: Type 'userId' is not assignable to type 'projectId'. 🎉
const myProjectId: projectId = myUserId;
Read more

You can define a "collection" of TypeScript types using enums and interfaces, like this:

enum MyList {

interface MyData {
  [MyList.A]: {color: string, enabled: boolean},
  [MyList.B]: string,
  [MyList.C]: any
Read more

In PHP, you can embed a variable into a string in these two ways:

$a = 'b';
echo "1: $a"; // outputs "1: b"
echo "2: {$a}"; // outputs "2: b"

However, you can also embed it in this arguably-more-confusing way:

echo "3: ${a}"; // outputs "3: b", but why!?

And, moreover:

$b = 'c';
echo "4: ${$a}"; // outputs "4: c". This is insanity.

Luckily, these two cases are being deprecated and going away in PHP 9.

Read more

There's a relatively new (but safe to use, because you don't care about IE anymore) native JS method to deep-copy (also referred to as "cloning") objects: structuredClone().

For example:

myObject = {a: 1, b: {c: 2}};
myDeepCopy = structuredClone(myObject);
Read more

You can restore a Git commit from a deleted branch by using the reflog command to see the commit, and then cherry-pick (not the only option) to bring it to your current branch.

Read more

The <base> tag can be used to alter all the links and images on the page. It also adds the ability to specify a default target for links. For example:

  <base href="https://example.com/" target="_blank">
Read more

You can add custom validation for Drupal entities by adding "constraints" (a concept from Symfony, the PHP framework on top of which Drupal is built) to the entity (using hook_entity_type_alter) or its individual fields (using hook_entity_bundle_field_info_alter). There are a number of different constraint classes already defined (UniqueField, Regex, etc.), or you could create your own.

This is better than adding validation on the node edit form, for example, since it will work anytime an entity is saved, such as when creating one programmatically.

Read more

When there are concurrency problems using Go's built-in map (which is not designed to be safe for concurrent use) and a fatal error happens, the stack traces for each goroutine will only show the access from the goroutine that crashed, and not for the other.

The reason for this seems to be that the second goroutine will have moved on by the time the stack trace is printed. Furthermore, fixing this in the language would have a performance penalty.

To help debug this issue, Go provides a built-in data race detector, which makes it show more obvious what happened. This has a significant performance cost, so it shouldn't be used in production.

Read more

You can generate different SSH keys for different Bitbucket accounts, for example, and configure them in ~/.ssh/config to use one or the other based on hostnames.

This config file will point a custom hostname to bitbucket.org (continuing the example), but specify a key different from the default.

Read more

In async functions in JavaScript, returning the result from an async function (i.e. a Promise object) is the same as returning the fulfilled value from that Promise. In code, assuming innerFn is async, this:

async function outerFn() {
  return await innerFn();

is the same as this:

async function outerFn() {
  return innerFn();
Read more

As with most things in JavaScript, there's a workaround to access the elements on a "closed" shadow DOM: hijacking the attachShadow method:

Element.prototype._attachShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = function () {
    return this._attachShadow( { mode: "open" } );
Read more

The 2-digit option in the Intl.DateTimeFormat API doesn't always do what you might expect. In particular, this piece of code doesn't produce a 2-digit number:

const dt = Date.parse('2000-01-02T03:04:05');

new Intl.DateTimeFormat('en-US', {minute: '2-digit'}).format(dt) === "4" // doesn't this look like it should be "04"?

However, it turns out this is not strictly a bug.

Read more

setTimeout usually takes a function and a delay argument, but it can also accept more arguments that are passed to the given function. This can make code easier to read, at the cost of having yet another way of doing the same thing.

Read more

PHP will (as of version 8) happily send a 200 response when there's a fatal error like, for example, a syntax error on an autoloaded class, even if you define an error handler using set_error_handler that will output a different HTTP status code.

The problem is, set_error_handler doesn't work on all error types. A workaround is adding a shutdown function using register_shutdown_function that checks the last error's type.

Read more

You can import ES6-style JavaScript modules dynamically using await import(filename);. For example:

const {default: renamedDefaultExport, namedExport1, namedExport2} = await import("./mymodule.js");
Read more

A null (zero) character will confuse PHP's password_* functions, when using bcrypt encryption (which is the default), so it's probably safe to just refuse any password with this character.

Read more

Trying to use undefined properties in PHP stdClass objects gives you a "warning" as of PHP 8 (it used to be a "notice" that, being realistic, you ignored).

One way to fix code that looks like the following is to use the new "null coalescing" operator (??):

$a = new stdClass;
$a->first = 1;

// This will give you a warning
$b = array($a->first, $a->second ?: NULL);

// This is fine
$c = array($a->first, $a->second ?? NULL);
Read more

You can send a request when a page is closed, either using the Fetch API with the keepalive option:

const url = "http://example.com/my/resource";
const data = {a: 1, b: 2}; // some data to be logged, such as usage statistics
const handler = () => fetch(url, {method: "POST", keepalive: true});
window.addEventListener("unload", handler);

Or the Beacon API:

const blob = new Blob([JSON.stringify(data)], {type: "application/json"});
const handler = () => navigator.sendBeacon(url, blob);
Read more

There is no JavaScript event for a URL change. There is one, however, for when the fragment changes (the part after the # symbol), called hashchange, and there is another, popstate, which doesn't always get triggered, for when the user clicks on the back or forward buttons or the history.back() or history.go() methods are called.

Read more

Add these lines to the top of a Makefile to load environment variables from a file. The minus sign lets it fail silently if the file doesn't exist:

-include .env
Read more

Some regex parsers (looking at you, JavaScript, but it's not the only one) can have serious problems with certain regular expressions such as the following:


Read more

The way the DOM works (which represents an HTML page in memory), text and tags such as <div> are both represented by "nodes" of different types organized in a tree structure so that, for example, text nodes become the "children" of element nodes.

A normalized DOM tree means that there are no empty text nodes or adjacent text nodes. The Node object has a normalize() method that makes sure of this.

Read more

When a development team is working on a PHP project that uses Composer with Git, it often happens that there are conflicts on the composer.lock file, on the "content hash" line.

To solve this, Composer provides a way to update the lock file from the packages currently installed, including the content hash value: composer update --lock. This does not try to update every package to the latest versions (as composer update would do).

Read more

"Balanced" cables provide protection against noise by having a copy of the audio signal in the opposite polarity. The receiving device will invert one of the signals and combine them, getting rid of any noise present in both signals (known as "common-mode interference"), since the noise will be "out of phase" with itself.

Read more

You can lock a row in a Postgres table by using FOR UPDATE in a SELECT query. The row will stay locked until the transaction is over.

Read more

In Drupal "entity queries", you can filter using fields from referenced entities. This will effectively do a SQL join on the query. For example:

$query = \Drupal::entityQuery('node')
  ->condition('uid.entity:user.mail', '%@example.com', 'LIKE');
Read more

There is more than one way of representing IP addresses (both v4 and v6). For example, is the same as 127.1!

Read more

By default, at least in Ubuntu, Docker container logs will grow indefinitely (in my case up to 412 GB, thus filling up my hard drive).

To prevent this, you can create a /etc/docker/daemon.json file with the following configuration:

Read more

If you require gzip compression on responses with types other than text/html, and you're running Nginx, you have to turn it on explicitly. To do so, you can add something like the following to a virtual host configuration file (usually located in /etc/nginx/sites-enabled), inside the server block:

gzip on;
gzip_types text/plain application/xml text/css text/javascript application/javascript image/svg+xml application/json;
Read more

The <q> element is an "inline version" of the more well-known <blockquote>. Interestingly, the browser will add quotes around it, so that Devs say <q>HTML is hard</q> gets rendered as Devs say “HTML is hard”.

Read more

Be careful inside try-catch blocks in Javascript async functions. If you don't use await, an error that's thrown might not stop the execution of subsequent code.

Read more

You can automatically generate smaller versions of your videos for faster editing in DaVinci Resolve, sometimes called "proxy files", using the "optimized media" option. In File > Project Settings you can define how they will be generated (resolution, encoding, etc.) and then you right-click on the videos and select "Generate optimized media".

Read more

As long as the types match, you can pass the return values from a function directly into another function as its parameters.

Read more

Go provides a "context" package to help keep track of data and timeouts, which is especially useful on servers where, for example, you want a piece of data to be available from when a middleware runs all throughout the request, or to limit how long a handler is allowed to run.

Read more

In a RAML file (used for creating API docs), you can add arbitrary content outside of the endpoints by using the documentation key, an array where each object has a title property and Markdown-formatted content property.

Read more

A quick and easy way to test if Docker is running correctly is to run this command:

$ docker run -p 80:80 nginx

Read more

Docker Toolbox (a "Legacy" version which is the only Docker you can use if you have Windows 10 Home and not Professional) needs an environment variable set so that docker-compose can adapt paths to Unix style, to be used in the volumes property in a docker-compose.yml file.

Read more

The innerText property magically converts newline characters to <br> elements. If you want to just set the text content of an element, you should use, well, textContent.

Apparently, the difference is that "innerText is aware of the rendered appearance of the text, while textContent is not."

Read more

You can use a Sinon.JS stub with the callsFake() method, passing it an existing function, to effectively "wrap" the function so that it registers each time you call and with which arguments, but in a way that it also seemingly works the same way as the original function does.

Read more

You can send data with the application/x-www-form-urlencoded content type (the one that encodes values similar to a query string, e.g. first=1&second=2) using a URLSearchParams object, like so:

fetch(url, {
  method: "POST",
  body: new URLSearchParams({first: 1, second: 2})
Read more

You can use "currentColor" as the color value in SVG elements, to pick up the color attribute from CSS. For example:

<div style="color: red;">
  <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
    <rect width="50" height="50" fill="currentColor" />
Read more

There's an API in Chrome and Firefox (that I know of) that lets you get localized strings with variable replacements from a JSON file that you provide.

var message = browser.i18n.getMessage("messageContent", target.url);
Read more

Arrays can be copied using spread syntax, introduced in ES6. To illustrate:

let a = [1, 2, 3];

// This won't work.
let b = a;
b[0] = 99;
console.log(a[0], b[0]); // prints "99 99"

// But this will.
let c = [...a]; // before ES6 there was an even uglier way of doing this using "slice", but let's never talk about that
c[0] = 12345;
console.log(a[0], c[0]); // prints "99 12345"
Read more

There are different types of functions in modern-ish JavaScript: regular, async, and generator functions. However, typeof returns "function" for all of them. One way (the only?) to differentiate between them is by using toString.call(myFunc).

Read more

Aggregate Mongo queries accept multiple steps, including SQL-style joins using $lookup. This will add a new property to the results, with an array of documents from the other collection. You can then use $unwind to make each result map to a single document from the other collection. Finally, $project can help you select only the fields you care about.

Read more

You can't directly export an "aggregate" Mongo to CSV using the mongoexport command, as it's intended for simpler data exports. However, there is a way to output the results of one such query to a new collection, which you can then export.

Read more

In Linux, you can make IPv4 traffic have a higher priority than IPv6 by running the following command:

sudo sh -c "echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf"

Read more

PHP supports the "data: stream wrapper" natively, so you don't have to do ugly string manipulation to get, for example, the data from a string such as data://text/plain;base64,SSBsb3ZlIFBIUAo=. Instead, you can do this:

$string = 'data://text/plain;base64,SSBsb3ZlIFBIUAo=';
$source = fopen($string, 'r');
$destination = fopen('myfile.txt', 'w');

stream_copy_to_stream($source, $destination);

Read more

If you run out of memory in Linux, you can create a file to hold additional memory using these commands:

/bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
/sbin/mkswap /var/swap.1
/sbin/swapon /var/swap.1
Read more

"Type embedding" allows for something close to inheritance in Go. If you add a type as a nameless parameter on a struct, the field and methods of that type are "promoted" to the new type.

Read more

Go stores interfaces as a pair of values: a type, and the actual value, and will only be equal to nil if both are.

As a consequence, a nil value stored in an interface variable, but as a pointer to another type, will not pass the == nil test.

Read more

On swing jazz, soloists usually play at a different swing ratio than drummers, and actually sync up with the off-beat of the drums. The on-beat will sometimes have a delay of as much as 100 ms.

Read more

Due to a bug in the original C code for the implementation of Javascript, this awesome thing happens:

const a = null;
console.log(typeof a); // prints "object"
Read more

Apparently, PHP can work just fine without loading a php.ini configuration file. I have no idea where it gets its default configuration from (for example, a value of 128M for memory_limit), but luckily phpinfo() will tell you where it's looking for a php.ini (search for "Configuration File" in its output), so you can just add the file in that path and it will get picked up.

Read more

Here's yet another one of Javascript's endless oddities: the switch statement uses strict comparison (think === instead of ==).

Read more

The Node and browser environments provide different functions, in addition to the process (Node-only) and window (browser-only) objects. If you want an NPM package to work on both, there's a way to specify different source files in the package.json file.

Read more

You can find a document, update and return it using a single method: findAndModify. This is useful to deal with concurrency issues when multiple clients are trying to process documents from a collection and you don't want two of them processing the same one.

Read more

Go relies on the operating system for timezone data, so when you do time.LoadLocation("America/Guayaquil"), it runs code that's different in different OSes. If you use a Docker container to run your code, it's possible to include this data in the form of a .zip file.

Read more

If you want to measure the time that it takes to run an operation, a common solution is to look at the current time before and after and compare the results. But what if the computer's time is changed between the two measurements? Then the result could be anything.

To solve this issue, computers provide a "monotonic clock", which doesn't change even if the computer's time does (maybe the system synchronizes with a time server, or the user just manually changed it). Some languages provide ways to access this value, so you have to decide what clock to use based on what you're doing with it.

Read more

In Ubuntu (and probably other OSes) you can create an empty file, resize it to a couple GBs, create a filesystem on it, and then mount it at any location. You can treat this as a virtual drive to, for example, limit the size of a directory:

Read more

There's a bunch of Web APIs that are pretty usable today:

  1. Detect page visibility
  2. Detect online state
  3. Vibration
  4. Detect orientation

...and more! clipboard, ambient light detection, battery status, etc.

Read more

You can run timers on the console object, like this:

console.timeEnd('a'); // outputs how much time has passed since the call above
Read more

From Wikipedia:

In linguistics, an eggcorn is an idiosyncratic substitution of a word or phrase for a word or words that sound similar or identical in the speaker's dialect (sometimes called oronyms). The new phrase introduces a meaning that is different from the original but plausible in the same context, such as "old-timers' disease" for "Alzheimer's disease".

Read more

A bugle is a wind instrument that can only play its key note and notes within its harmonic series, for example, C3 G3 C4 E4 G4. To play different notes, one must change how the lips are placed on the mouthpiece of the instrument, which causes air to vibrate at different speeds, but the options are physically limited to integer multipliers of the base frequency.

Read more

You can think of the denominator of a time signature as a whole note split in as many pieces, so that a time signature that is "weird" (the name is actually "irrational", nothing to do with the mathematical sense) like 5/7 now makes sense as "five sevenths of a whole note", or a bit longer than a 2/4 measure.

Read more

There's a nice utility that you can use to kill a process based on the port it's listening to, so for example if you have a server listening on port 80, you can run $ fkill :80 and it will murder it.

Only problem, it's made using Javascript, but if you're OK with having Node and plain-text JS files in your bin folder, you can install it with $ npm install --global fkill-cli.

Read more

Javascript's Date object has a bunch of methods to format dates as strings, including toLocaleDateString(). This method has options for controlling the format, which include language but also more granular options such as "use 2-digit years" or "show long weekday names".

Here are some examples (tests were done in Chrome 64):

Read more

The most common tuning system in western music nowadays involves dividing an octave into 12 equally spaced "semitones", called "equal temperament". In this system, the octave interval (frequency ratio 2:1) is the only "perfect" one, and, for example, a "perfect fifth" (frequency ratio 3:2) doesn't exactly match a "fifth" (seven semitones). This is the solution people came up with, and we've been using it happily for a while now, but there are other equally valid ways to split the octave.

Read more

In order to use a variable as an object's key, ES6 introduced something called "computed property names", where you add brackets to your variable and it gets replaced with its value.

Read more

You can undo the "eject" operation of a Create React App app by adding the react-scripts package back and changing a couple of lines on the package.json file to their defaults. You can lose those /config and /scripts directories too. The only really ugly thing I found on my test (admittedly on a very simple app which is probably not at all representative of the real world) is that a number of packages were added without an easy way to get rid of. But hey, doesn't that sound like good old npm anyway?

Read more

There's a simple algorithm that uses the Bayes theorem that can be used to classify documents, using their text tokenized into individual words, into categories (e.g. tags on a website). The classifier needs to be trained with existing data, and then it will return which categories a new document probably belongs to.

Read more

JSON.parse() has an optional second parameter meant for a "reviver" function. This function will receive all keys and values from the parsed string, so you can do modifications to the result. This is useful, for example, to convert date strings to objects automatically.

Read more

Object IDs in Mongo store several variables (screenshot from MongoChef), including the time it was created, a machine identifier, a process ID and an internal counter.

Screenshot showing an object ID and its parsed values

Read more

In the Go language, when you define an interface, you only need to implement the functions and your type automatically "implements" that interface, without explicitly saying so.

Read more

…how to lock a piece of code so that it's guaranteed to only run once at a time. If it's running and another thread (or Goroutine in my case) reaches the same piece of code, it will wait for the first process to finish before continuing its execution.

I'm using it to lock an entire function, but apparently it works for any section of code.

Read more

Running tests with coverage on the Goland IDE is really easy, you just write the test and it gives you a "play icon" button to the left of each function, and after it runs you get the coverage report in a separate window and within the source code as well, telling you exactly which lines are covered.

Read more
Mastodon Mastodon