Skip to content
tinytip

Latest tips / 9

Angular HttpClient accepts query params as object

November 17, 2021
#angular #http

When making an HTTP request with query params in Angular using the HttpClient you don't need to compose the URL by yourself. Instead, you can pass the params as an object or an HttpParams instance.

  // Instead of passing query params as part of the URL...
function fetchSomeData() {
return this.httpClient.get('/my/endpoint?id=2');
}

// ... you can pass them as object
function fetchSomeData() {
const params: { id: 2 };
return this.httpClient.get('/my/endpoint', { params });
}

// ... or HttpParams
function fetchSomeData() {
const params = new HttpParams().set('id', 2);
return this.httpClient.get('/my/endpoint', { params });
}

How to use Array.map() with objects

October 9, 2021
#javascript

The Array.map() function allows to to map each value of an array to a new value. If you want to map an object - its keys, values or both - you can use Object.entries() and Object.fromEntries() to convert the object to an array and back to an object.

The Object.entries() function expects an object and returns an array with key-value pairs in the form of an array [key, value]. Then you can use Array.map() to map the keys and/or values.

The transformed array can be converted back to an object by using Object.fromEntries().

// 1. Create an object
const obj = { one: 1, two: 2, three: 3 };

// 2. Convert the object to an array of key-value pairs
const entries = Object.entries(obj);
// [ ["one", 1], ["two", 2], ["three", 3] ]

// 3. Map the array to new keys or values
const transformed = entries.map(([key, value]) => {
// Change the value to a string and add leading zeros
return [key, value.toString().padStart(3, "0")];
});

// 4. Convert the transformed array back to an object
const finalResult = Object.fromEntries(transformed);
// { one: "001", two: "002", three: "003" }

Style Angular Components based on their context

October 9, 2021
#angular #css

The Angular :host-context() selector allows you to style your component based on some conditions outside the component - for example based on a class set on the body element - without the need to set view encapsulation to none.

The selector will look for a matching element in any ancestor of your component up to the document root.

:host-context(.dark-theme) .my-component {
/* Styles are applied when there is a
"dark-theme" class on any ancestor */

}

This is not limited to CSS class selectors but works with any valid CSS selector.

:host-context([theme="dark"]) .my-component {
/* Styles are applied when there is an ancestor
that has an attribute theme="dark" */

}

The CSS list-style property affects screen readers

October 9, 2021
#html #a11y
Credits: Scott O'Hara

If you have a ul element in your HTML and you set list-style: none via CSS (via inline styles, a style tag or an external stylesheet), your list will not be announced as a list anymore with VoiceOver + Safari on macOS.

<!-- VoiceOver + Safari will not announce this as a list -->
<ul style="list-style:none">
<li>...</li>
<li>...</li>
<li>...</li>
</ul>

Add the role attribute to the ul element to fix this behavior.

<!-- VoiceOver + Safari will now announce the list -->
<ul role="list" style="list-style:none">
<li>...</li>
<li>...</li>
<li>...</li>
</ul>

Alpine.js accepts a custom prefix for directives

September 21, 2021
#alpinejs

Alpine.js uses the x- prefix for directives by default (e.g. x-if). This prefix can be customized using Alpine.prefix().

Alpine.prefix("xyz-"); // Define your custom prefix
Alpine.start();
<!-- Use your custom prefix for all directives -->
<template xyz-if="user">
<a xyz-bind:href="user.profileUrl" xyz-text="user.name"></a>
</template>

This can be useful to prevent clashes when integrating Alpine into existing apps / markup or to get valid HTML markup that passes the W3C validator by using data-x- as prefix.