### Install ngxtension
Source: https://ngxtension.dev/
Install ngxtension using npm, pnpm, or yarn.
```bash
npm install ngxtension
# or
pnpm add ngxtension
# or
yarn add ngxtension
```
--------------------------------
### Install ngxtension/gestures
Source: https://ngxtension.dev/utilities/dom-events/gesture
Install the gesture package using npm.
```bash
npm i @use-gesture/vanilla
```
--------------------------------
### Install ngxtension Plugin with npm
Source: https://ngxtension.dev/getting-started/installation
Install the ngxtension plugin as a development dependency using npm. This command is used for both Angular and Nx projects.
```bash
npm install -D ngxtension-plugin
```
--------------------------------
### Configure DisplayNamesPipe Options
Source: https://ngxtension.dev/utilities/intl/intl
Customize DisplayNamesPipe by providing options using `provideDisplayNamesOptions`. This example sets the `localeMatcher` and `style` for the pipe.
```typescript
import {Component} from "@angular/core";
import {DisplayNamesPipe, provideDisplayNamesOptions} from 'ngxtension/intl';
@Component({
selector: 'app-root',
standalone: true,
imports: [DisplayNamesPipe],
providers: [
provideDisplayNamesOptions({
localeMatcher: 'best fit',
style: 'long',
})
],
template: '
{{ 'en' | displayNames }}
'
})
```
--------------------------------
### Angular Component Before Host Binding Migration
Source: https://ngxtension.dev/utilities/migrations/host-binding-migration
Example of an Angular component using @HostBinding and @HostListener decorators before migration.
```typescript
import { Component, HostBinding, HostListener } from '@angular/core';
@Component({
/* ... */
})
export class CustomSlider {
@HostBinding('attr.aria-valuenow')
value: number = 0;
@HostBinding('tabIndex')
getTabIndex() {
return this.disabled ? -1 : 0;
}
@HostListener('keydown', ['$event'])
updateValue(event: KeyboardEvent) {
/* ... */
}
}
```
--------------------------------
### Usage with Custom Start Point
Source: https://ngxtension.dev/utilities/directives-templates/repeat-pipe
Specify a 'startAt' value as the second argument to the RepeatPipe to change the starting point of the iterations.
```typescript
import { Component } from '@angular/core';
import { RepeatPipe } from 'ngxtension/repeat-pipe';
@Component({
imports: [RepeatPipe],
template: '
@for (i of 3 | repeat: 10; track i) {
{{ i }}
}
',
})
export class App {}
```
--------------------------------
### Repeat Directive Output Example
Source: https://ngxtension.dev/utilities/directives/repeat
Illustrates the expected HTML output when using the Repeat directive to iterate 3 times.
```html
```
--------------------------------
### Example: Automatic Synchronization (Default)
Source: https://ngxtension.dev/utilities/injectors/linked-query-param
Illustrates how the source signal's value is automatically moved to a new query parameter key when `automaticallySynchronizeOnKeyChange` is true.
```typescript
export class ExampleComponent {
readonly keySignal = signal('search');
readonly searchValue = signal(null);
readonly searchParam = linkedQueryParam(this.keySignal, {
source: this.searchValue,
automaticallySynchronizeOnKeyChange: true, // default
});
// Initial: key = 'search', searchValue = null, URL: no param
// User types 'hello'
searchValue.set('hello');
// → URL: ?search=hello
// Change key to 'query'
keySignal.set('query');
// → URL: ?query=hello (value automatically moved to new key)
// → searchValue() = 'hello' (unchanged)
}
```
--------------------------------
### DisplayNamesPipe Error Handling Example
Source: https://ngxtension.dev/utilities/intl/intl
If an error occurs with DisplayNamesPipe, it returns the input value and logs an error to the console. This example shows how an invalid value is handled.
```html
{{ 'any-nonvalid-value' | displayNames: 'language' }}
```
--------------------------------
### Angular Component After Host Binding Migration
Source: https://ngxtension.dev/utilities/migrations/host-binding-migration
Example of the same Angular component after migrating to the 'host' property.
```typescript
import { Component } from '@angular/core';
@Component({
host: {
'[attr.aria-valuenow]': 'value',
'[tabIndex]': 'disabled ? -1 : 0',
'(keydown)': 'updateValue($event)',
},
})
export class CustomSlider {
value: number = 0;
disabled: boolean = false;
updateValue(event: KeyboardEvent) {
/* ... */
}
}
```
--------------------------------
### Initializing Root Tokens with ENVIRONMENT_INITIALIZER
Source: https://ngxtension.dev/utilities/dependency-injection/create-injection-token
Shows how to initialize root tokens within `ENVIRONMENT_INITIALIZER` using the provider function returned by `createInjectionToken`. This method simplifies the setup for root-level dependencies.
```typescript
const [
injectOne /* skip provider fn */ /* skip the token */,
,
,
provideOneInitializer,
] = createInjectionToken(() => 1);
bootstrapApplication(App, {
providers: [provideOneInitializer()],
});
```
--------------------------------
### paramToNumber Parser Examples
Source: https://ngxtension.dev/utilities/injectors/linked-query-param
Illustrates the behavior of the `paramToNumber` parser with and without default values, showing how it handles valid, invalid, and missing query parameters.
```typescript
import { linkedQueryParam, paramToNumber } from 'ngxtension/linked-query-param';
// Returns number | null if param is not present or invalid
const page = linkedQueryParam('page', {
parse: paramToNumber(),
});
// URL: ?page=5 → signal: 5
// URL: ?page=abc → signal: null
// URL: (no param) → signal: null
// Returns number (never null) with default value
const pageWithDefault = linkedQueryParam('page', {
parse: paramToNumber({ defaultValue: 1 }),
});
// URL: (no param) → signal: 1
// URL: ?page=abc → signal: 1 (invalid value falls back to default)
// URL: ?page=5 → signal: 5
```
--------------------------------
### Non-Pure Function Usage (Commented Out)
Source: https://ngxtension.dev/utilities/directives-templates/call-apply
This commented-out example demonstrates how attempting to use a non-pure function with ApplyPipe would result in an error. It highlights the requirement for pure functions.
```html
```
--------------------------------
### paramToBoolean Parser Examples
Source: https://ngxtension.dev/utilities/injectors/linked-query-param
Demonstrates the `paramToBoolean` parser, explaining how it interprets string values like 'true' and handles missing or other string values, including with default values.
```typescript
import {
linkedQueryParam,
paramToBoolean,
} from 'ngxtension/linked-query-param';
// Returns boolean | null if param is not present
const showHidden = linkedQueryParam('showHidden', {
parse: paramToBoolean(),
});
// URL: ?showHidden=true → signal: true
// URL: ?showHidden=false → signal: false
// URL: ?showHidden=anything → signal: false
// URL: (no param) → signal: null
// Returns boolean (never null) with default value
const showHiddenWithDefault = linkedQueryParam('showHidden', {
parse: paramToBoolean({ defaultValue: true }),
});
// URL: (no param) → signal: true (default)
// URL: ?showHidden=true → signal: true
```
--------------------------------
### Use options with global params
Source: https://ngxtension.dev/utilities/injectors/inject-params
Apply options such as parsing to global route parameters. This example parses the 'id' parameter as a number.
```typescript
@Component()
class TestComponent {
// Parse param as number
userId = injectParams.global('id', {
parse: numberAttribute,
});
}
```
--------------------------------
### createRepeat as Syntactic Sugar
Source: https://ngxtension.dev/utilities/rxjs-operators/create-repeat
This example demonstrates the equivalent functionality of createRepeat using RxJS's Subject and repeat operator directly. It shows how createRepeat simplifies the process.
```typescript
@Component({
...,
template: `
`
})
export class SomeComponent {
readonly repeat$ = new Subject();
readonly #sayHello = rxEffect(of('hello').pipe(repeat({ delay: () => repeat$ }), console.log);
}
```
--------------------------------
### Basic Usage of on with Multiple Dependencies
Source: https://ngxtension.dev/utilities/effects-side-effects/on
Use `on` to create an effect that runs when any of the provided signals change. This example demonstrates tracking changes in `count` and `doubleJson` signals.
```typescript
import { effect, signal } from '@angular/core';
import { on } from 'ngxtension/reactive-on';
const count = signal(0);
const doubleJson = signal(0);
effect(
on([count, doubleJson], ([c, d]) => {
console.log(`Count: ${c}, Double: ${d}`);
}),
);
```
--------------------------------
### withLatestFrom Example
Source: https://ngxtension.dev/utilities/operators/take-latest-from
Demonstrates the usage of withLatestFrom. This operator waits for the source observable to emit and then combines it with the latest values from other observables.
```typescript
src$.pipe(withLatestFrom(data$)).subscribe();
```
--------------------------------
### Transform all route params
Source: https://ngxtension.dev/utilities/injectors/inject-params
Inject all route parameters and transform them using a provided function. This example extracts the keys of the parameters.
```typescript
@Component()
class TestComponent {
paramsKeys = injectParams((params) => Object.keys(params)); // returns a signal with the keys of the params
}
```
--------------------------------
### Specify Style and Locale for DisplayNamesPipe
Source: https://ngxtension.dev/utilities/intl/intl
You can specify the style and locale as parameters to the DisplayNamesPipe to override the default settings. This example displays the language name in German.
```html
```
--------------------------------
### Example: Without Automatic Synchronization
Source: https://ngxtension.dev/utilities/injectors/linked-query-param
Shows how the query parameter remains unchanged when the key is updated if `automaticallySynchronizeOnKeyChange` is false, until the source signal is next updated.
```typescript
export class ExampleComponent {
readonly keySignal = signal('param1');
readonly valueSignal = signal('value1');
readonly param = linkedQueryParam(this.keySignal, {
source: this.valueSignal,
automaticallySynchronizeOnKeyChange: false,
});
// Initial: key = 'param1', value = 'value1', URL: ?param1=value1
// Change key to 'param2'
keySignal.set('param2');
// → URL: ?param1=value1 (unchanged, param2 not yet set)
// → valueSignal() = 'value1' (unchanged)
// Now update the value
valueSignal.set('value2');
// → URL: ?param2=value2 (now updates to new key)
// → Old param1 is removed
}
```
--------------------------------
### Get a specific route param
Source: https://ngxtension.dev/utilities/injectors/inject-params
Inject the value of a specific route parameter by its name. This example retrieves the 'id' parameter.
```typescript
@Component({
template: `
@if (user(); as user) {
{{ user.name }}
} @else {
No user!
}
`,
})
class TestComponent {
userId = injectParams('id'); // returns a signal with the value of the id param
user = derivedFrom(
[this.userId],
switchMap((id) => this.userService.getUser(id).pipe(startWith(null))),
);
}
```
--------------------------------
### Get a specific param from the route hierarchy
Source: https://ngxtension.dev/utilities/injectors/inject-params
Access a specific route parameter from anywhere in the route hierarchy. This example retrieves the 'id' parameter.
```typescript
@Component()
class ParentComponent {
// Gets the 'id' param from anywhere in the route hierarchy
id = injectParams.global('id');
}
```
--------------------------------
### Run SFC Migration for All Projects
Source: https://ngxtension.dev/utilities/migrations/sfc-migration
Execute the schematic to convert all components in the project to SFC format.
```bash
ng g ngxtension-plugin:convert-to-sfc
```
--------------------------------
### Example: Sum Array Elements with reduceArray
Source: https://ngxtension.dev/utilities/operators/reduce-array
Demonstrates summing all elements in an array emitted by an Observable. The reduceArray operator accumulates the sum starting from an initial value of 0.
```typescript
const source$ = of([1, 2, 3]);
const reduced$ = source$.pipe(reduceArray((acc, e) => acc + e, 0));
// Output: 6
```
--------------------------------
### Provide Initial Value for Async Sources
Source: https://ngxtension.dev/utilities/signal-async/merge-from
Prevent errors with asynchronous sources by providing an `initialValue` in the options object. This sets the starting value for the resulting Signal.
```typescript
import { signal } from '@angular/core';
import { mergeFrom } from 'ngxtension/merge-from';
import { delay, of, pipe, switchMap } from 'rxjs';
const runnerOne = signal({ name: 'Naruto', time: '12:43PM' });
const runnerTwo = signal({ name: 'Goku', time: '12:44PM' });
const lastRunner = mergeFrom(
[runnerOne, runnerTwo],
pipe(
switchMap((runner) => {
return of('The last runner to arive was: ' + runner.name).pipe(
delay(1000),
);
}),
),
{ initialValue: 'Waiting for someone to arrive...' },
);
// You can copy the above example inside a component constructor and see the result in the console.
```
--------------------------------
### Default Value for Linked Query Param
Source: https://ngxtension.dev/utilities/injectors/linked-query-param
This example demonstrates how to set a default value for a linked query parameter. If the 'page' query parameter is not present in the URL, the 'page' signal will be initialized to '1'. This ensures a predictable starting state for features like pagination.
```typescript
// Default to page 1
page = linkedQueryParam('page', {
defaultValue: 1,
});
```
--------------------------------
### Initialize ngxtension Plugin in Nx
Source: https://ngxtension.dev/getting-started/installation
Generate the ngxtension plugin initialization files for an Nx project using the Nx CLI.
```bash
nx g ngxtension-plugin:init
```
--------------------------------
### Constructor
Source: https://ngxtension.dev/utilities/signal-primitives/signal-map
Creates a new SignalMap instance, optionally initialized with entries.
```APIDOC
## Constructor
### Description
Creates a new `SignalMap` instance, optionally initialized with entries.
### Parameters
#### Path Parameters
- `entries` (readonly (readonly [K, V])[] | null) - Optional - Array of key-value pairs to initialize the map.
### Request Example
```typescript
const map = new SignalMap([
['a', 1],
['b', 2],
]);
```
```
--------------------------------
### ResizeOptions and provideResizeOptions()
Source: https://ngxtension.dev/utilities/dom-events/resize
Configuration options for resize behavior and a function to provide these options globally.
```APIDOC
## ResizeOptions and provideResizeOptions()
### Description
Allows customization of resize event observation behavior. `ResizeOptions` can be provided globally or to specific component trees.
### Usage
#### Per Instance
Pass `ResizeOptions` to `injectResize` or the `[ngxResizeOptions]` input of the `NgxResize` directive.
```typescript
// Using injectResize
injectResize(someOptions);
// Using NgxResize directive
//
```
#### Global Configuration
Use `provideResizeOptions()` to set global options for the application or a route.
```typescript
// Standalone Application
import { bootstrapApplication } from '@angular/platform-browser';
import { provideResizeOptions } from 'ngxtension/resize';
bootstrapApplication(App, {
providers: [provideResizeOptions(globalOptions)]
});
// AppModule
import { NgModule } from '@angular/core';
import { provideResizeOptions } from 'ngxtension/resize';
@NgModule({
providers: [provideResizeOptions(globalOptions)]
})
export class AppModule {}
// Route Providers
const route = {
path: 'some-path',
providers: [provideResizeOptions(subTreeGlobalOptions)]
};
```
```
--------------------------------
### SignalMap Initialization
Source: https://ngxtension.dev/utilities/signal-primitives/signal-map
Shows how to initialize a SignalMap, either as an empty map or with an array of initial key-value pairs.
```typescript
// Empty map
const map = new SignalMap();
// With initial entries
const map = new SignalMap([
['a', 1],
['b', 2],
['c', 3],
]);
```
--------------------------------
### Get the size of SignalSet
Source: https://ngxtension.dev/utilities/signal-primitives/signal-set
Gets the number of values currently in the set. This property tracks structure changes.
```typescript
const count = computed(() => set.size);
```
--------------------------------
### Basic createEffect Usage
Source: https://ngxtension.dev/utilities/effects-side-effects/create-effect
Demonstrates a basic usage of createEffect to log doubled values from an interval. The effect is started by calling the created effect function with an observable stream.
```typescript
@Component({})
export class Some {
log = createEffect(
pipe(
map((value) => value * 2),
tap(console.log.bind(console, 'double is -->')),
),
);
ngOnInit() {
// start the effect
this.log(interval(1000));
}
}
```
--------------------------------
### Run Host Binding Migration Schematic for All Projects
Source: https://ngxtension.dev/utilities/migrations/host-binding-migration
Command to execute the schematic for all projects within the Angular application.
```bash
ng g ngxtension-plugin:convert-host-binding
```
--------------------------------
### Get Document Visibility Signal
Source: https://ngxtension.dev/utilities/browser-apis/inject-document-visibility
Call injectDocumentVisibility to get a signal that reflects the document's visibility state. Use an effect to log changes to the signal.
```typescript
const visibilityState = injectDocumentVisibility();
effect(() => {
console.log(visibilityState());
});
```
--------------------------------
### Run Host Binding Migration Schematic for a Specific Project
Source: https://ngxtension.dev/utilities/migrations/host-binding-migration
Command to execute the schematic for a specified project by name.
```bash
ng g ngxtension-plugin:convert-host-binding --project=
```
--------------------------------
### Example: Removing Undefined and Null Values
Source: https://ngxtension.dev/utilities/operators/filter-nil
This example shows how to use filterNil to remove both undefined and null values from an observable stream, resulting in a stream of only defined, non-null numbers.
```typescript
const source$ = of(undefined, null, 1, 2, null);
const filtered$ = source$.pipe(filterNil());
// Output: 1, 2
```
--------------------------------
### Run Host Binding Migration Schematic with Nx
Source: https://ngxtension.dev/utilities/migrations/host-binding-migration
Command to execute the schematic within an Nx monorepo, replacing 'ng' with 'nx'.
```bash
nx g ngxtension-plugin:convert-host-binding --project=
```
--------------------------------
### Example: Prevent Numbers in Text
Source: https://ngxtension.dev/utilities/forms/not-pattern
Instantiate a `FormControl` with `notPattern` to ensure the value does not contain any digits. The first example shows a valid state, while the second demonstrates an invalid state.
```typescript
// Prevent numbers in text
const noNumbersControl = new FormControl('abc', notPattern(/[0-9]/));
console.log(noNumbersControl.errors); // null - valid because 'abc' has no numbers
const withNumbersControl = new FormControl('abc123', notPattern(/[0-9]/));
console.log(withNumbersControl.errors);
// {notPattern: {disallowedPattern: '/[0-9]/', actualValue: 'abc123'}}
```
--------------------------------
### Custom Error State Matcher Example
Source: https://ngxtension.dev/utilities/forms/control-error
An example of a custom StateMatcher that considers a control in an error state solely based on its status being 'INVALID'. It emits whenever the statusChanges observable emits.
```typescript
export const customErrorStateMatcher: StateMatcher = (control) =>
control.statusChanges.pipe(
startWith(control.status),
map((status) => status === 'INVALID'),
);
```
--------------------------------
### Use injectNetwork to Get Network State
Source: https://ngxtension.dev/utilities/browser-apis/inject-network
Call injectNetwork to get a readonly NetworkState object. This object contains signals for various network properties. Use this in effects or other reactive contexts to react to network changes.
```typescript
const networkState = injectNetwork();
effect(() => {
console.log(this.network.type());
console.log(this.network.downlink());
console.log(this.network.downlinkMax());
console.log(this.network.effectiveType());
console.log(this.network.rtt());
console.log(this.network.saveData());
console.log(this.network.online());
console.log(this.network.offlineAt());
console.log(this.network.onlineAt());
console.log(this.network.supported());
});
```
--------------------------------
### Initialize ngxtension Plugin in Angular
Source: https://ngxtension.dev/getting-started/installation
Generate the ngxtension plugin initialization files for an Angular project using the Angular CLI.
```bash
ng g ngxtension-plugin:init
```
--------------------------------
### Run Host Binding Migration Schematic for a Specific File
Source: https://ngxtension.dev/utilities/migrations/host-binding-migration
Command to execute the schematic for a specific component or directive file.
```bash
ng g ngxtension-plugin:convert-host-binding --path=
```
--------------------------------
### Get the leaf activated route in a component
Source: https://ngxtension.dev/utilities/router/inject-leaf-activated-route
Call `injectLeafActivatedRoute` within a component to get a signal containing the current leaf activated route. This signal can then be used to display route information like URL segments and parameters.
```typescript
@Component({
standalone: true,
template: `
`,
})
class MyComponent {
leafRoute = injectLeafActivatedRoute();
}
```
--------------------------------
### SignalSet Initialization
Source: https://ngxtension.dev/utilities/signal-primitives/signal-set
Shows different ways to initialize a SignalSet, including creating an empty set, initializing with values, and how duplicates are handled.
```typescript
// Empty set
const set = new SignalSet();
// With initial values
const set = new SignalSet(['a', 'b', 'c']);
// Duplicates are automatically handled
const set = new SignalSet(['a', 'b', 'a']); // size: 2
```
--------------------------------
### size
Source: https://ngxtension.dev/utilities/signal-primitives/signal-set
Gets the number of values in the set. This property tracks structure changes.
```APIDOC
## size: number
### Description
Gets the number of values currently in the set. This property tracks structure changes.
### Method
- Not applicable (property access)
### Endpoint
- Not applicable (property access)
### Parameters
#### Path Parameters
- None
#### Query Parameters
- None
#### Request Body
- None
### Parameters
- None
### Request Example
```typescript
const count = computed(() => set.size);
```
### Response
#### Success Response (number)
- The number of values in the set.
### Response Example
```typescript
// Example response is implicit in the return type
```
```
--------------------------------
### size
Source: https://ngxtension.dev/utilities/signal-primitives/signal-map
Gets the number of entries in the map. This property tracks structure changes.
```APIDOC
## size
### Description
Gets the number of entries in the map. This property tracks structure changes.
### Returns
A `number` representing the number of entries in the map.
### Request Example
```typescript
const count = computed(() => map.size);
```
```
--------------------------------
### Basic SignalMap Usage
Source: https://ngxtension.dev/utilities/signal-primitives/signal-map
Demonstrates basic initialization, setting values, and using computed signals for size and specific key retrieval. Includes an effect to log map size changes.
```typescript
import { SignalMap } from 'ngxtension/collections';
import { Component, computed, effect } from '@angular/core';
@Component({
selector: 'app-user-manager',
template: `
Total users: {{ totalUsers() }}
Admin name: {{ adminName() }}
`,
})
export class UserManagerComponent {
readonly users = new SignalMap();
readonly totalUsers = computed(() => this.users.size);
readonly adminName = computed(() => this.users.get(1)?.name ?? 'No admin');
constructor() {
// Initialize with data
this.users.set(1, { name: 'Alice', role: 'admin' });
this.users.set(2, { name: 'Bob', role: 'user' });
// React to changes
effect(() => {
console.log('User count:', this.users.size);
});
}
}
```
--------------------------------
### Get all values from SignalSet
Source: https://ngxtension.dev/utilities/signal-primitives/signal-set
Returns an iterator of all values in the set. This operation tracks structure changes.
```typescript
const allValues = computed(() => Array.from(set.values()));
```
--------------------------------
### Get all keys from SignalSet
Source: https://ngxtension.dev/utilities/signal-primitives/signal-set
Returns an iterator of all values in the set. This operation tracks structure changes.
```typescript
const allKeys = computed(() => Array.from(set.keys()));
```
--------------------------------
### Run SFC Migration for a Specific Component
Source: https://ngxtension.dev/utilities/migrations/sfc-migration
Target a specific component or directive for conversion by providing its file path.
```bash
ng g ngxtension-plugin:convert-to-sfc --path=
```
--------------------------------
### SignalMap size Property
Source: https://ngxtension.dev/utilities/signal-primitives/signal-map
Gets the number of entries currently in the map. This property tracks structure changes.
```typescript
const count = computed(() => map.size);
```
--------------------------------
### NgxDrag Directive Usage in Component
Source: https://ngxtension.dev/utilities/dom-events/gesture
Component setup for using the NgxDrag directive and handling drag events.
```typescript
@Component({
imports: [NgxDrag],
templateUrl: './app.html',
})
export class App {
onDrag(state: NgxInjectDrag['state']) {
// fire every time a drag event happens
}
}
```
--------------------------------
### Basic Usage with @for
Source: https://ngxtension.dev/utilities/directives-templates/repeat-pipe
Use the RepeatPipe with Angular's @for syntax to loop a specified number of times, starting from 0.
```typescript
import { Component } from '@angular/core';
import { RepeatPipe } from 'ngxtension/repeat-pipe';
@Component({
imports: [RepeatPipe],
template: '
@for (i of 3 | repeat; track i) {
{{ i }}
}
',
})
export class App {}
```
--------------------------------
### Import connect utility
Source: https://ngxtension.dev/utilities/signal-async/connect
Import the connect function from the ngxtension library.
```typescript
import { connect } from 'ngxtension/connect';
```
--------------------------------
### Basic SignalSet Usage
Source: https://ngxtension.dev/utilities/signal-primitives/signal-set
Demonstrates basic usage of SignalSet, including adding elements, computing derived signals for size and membership, and reacting to changes with an effect.
```typescript
import { SignalSet } from 'ngxtension/collections';
import { Component, computed, effect } from '@angular/core';
@Component({
selector: 'app-tag-manager',
template: `
Total tags: {{ totalTags() }}
Has 'angular': {{ hasAngular() }}
`,
})
export class TagManagerComponent {
tags = new SignalSet();
totalTags = computed(() => this.tags.size);
hasAngular = computed(() => this.tags.has('angular'));
constructor() {
// Initialize with data
this.tags.add('angular');
this.tags.add('typescript');
this.tags.add('rxjs');
// React to changes
effect(() => {
console.log('Tag count:', this.tags.size);
});
}
}
```
--------------------------------
### Filter Even Numbers with filterArray
Source: https://ngxtension.dev/utilities/operators/filter-array
An example demonstrating how to filter an Observable emitting an array to keep only even numbers.
```typescript
const source$ = of([1, 2, 3, 4, 5]);
const filtered$ = source$.pipe(filterArray((element) => element % 2 === 0));
```
--------------------------------
### Injecting and Using a Basic Local Storage Signal
Source: https://ngxtension.dev/utilities/browser-apis/inject-local-storage
Injects a string signal for 'username' and demonstrates setting, updating, and logging its value. Updates to this signal are reflected in local storage and can trigger a storage event.
```typescript
const username = injectLocalStorage('username');
username.set('John Doe');
username.update((name) => 'Guest ' + name);
effect(() => {
console.log(username());
});
```
--------------------------------
### Get all route params as a signal
Source: https://ngxtension.dev/utilities/injectors/inject-params
Inject all current route parameters as a signal. Ensure the component is part of the routing context.
```typescript
@Component({
standalone: true,
template: '
{{params() | json}}
',
})
class TestComponent {
params = injectParams();
}
```
--------------------------------
### Configure PluralRulesPipe with Options
Source: https://ngxtension.dev/utilities/intl/intl
Customize PluralRulesPipe behavior by using the providePluralRulesOptions provider. This example sets the pluralization type to 'ordinal'.
```typescript
import {Component} from "@angular/core";
import {PluralRulesPipe, providePluralRulesOptions} from 'ngxtension/intl';
@Component({
selector: 'app-root',
standalone: true,
imports: [PluralRulesPipe],
providers: [
providePluralRulesOptions({
type: 'ordinal',
})
],
template: '
{{ 1 | pluralRules }}
'
})
```
--------------------------------
### Usage Example: Combining Signals and Observables
Source: https://ngxtension.dev/utilities/signals/to-observable-signal
Demonstrates how to use `toObservableSignal` to convert a signal to an observable, and then use RxJS operators like `pipe` and `switchMap`. Also shows creating a computed signal.
```typescript
@Component({
selector: 'my-app',
standalone: true,
imports: [CommonModule],
template: `
Signal A: {{ a() }}
Observable A: {{ a | async }}
Observable B (A*2): {{ b | async }}
Signal C (A*3): {{ c() }}
`,
})
export class App {
a = toObservableSignal(signal(0));
b = this.a.pipe(
switchMap((v) => {
return of(v * 2);
}),
);
c = computed(() => this.a() * 3);
constructor() {
setInterval(() => this.a.set(1), 10000);
setInterval(() => this.a.update((v) => v + 1), 1000);
}
}
```
--------------------------------
### createRepeat API Documentation
Source: https://ngxtension.dev/utilities/rxjs-operators/create-repeat
Details the arguments and return value of the createRepeat function.
```APIDOC
## `createRepeat`
### Description
Creates an RxJS `repeat` operator with an `emit` method for controlling stream repetition.
### Overloads
#### Overload 1: With `globalCount` and `destroyRef`
- **`globalCount`** (`number`, optional, default: `undefined`): The number of times the source Observable items are repeated globally. A count of 0 results in an empty Observable.
- **`destroyRef`** (`DestroyRef`, optional, default: `undefined`): The `DestroyRef` to use when `createRepeat` is called outside an injection context.
#### Overload 2: With `destroyRef` only
- **`destroyRef`** (`DestroyRef`, optional, default: `undefined`): The `DestroyRef` to use when `createRepeat` is called outside an injection context.
### Returned `repeat` operator
This operator accepts an optional `count` argument.
- **`count`** (`number`, optional, default: `undefined`): The number of times the source Observable items are repeated. A count of 0 results in an empty Observable.
### Usage Example
```typescript
import { createRepeat } from 'ngxtension/create-repeat';
import { Component } from '@angular/core';
import { of } from 'rxjs';
import { rxEffect } from 'ngxtension/rx-effect';
@Component({
selector: 'app-example',
template: `
`
})
export class ExampleComponent {
readonly repeat = createRepeat();
// Will log 'hello' directly, then each time the 'Repeat' button is clicked
readonly #sayHello = rxEffect(of('hello').pipe(this.repeat()), console.log);
}
```
### See Also
- `rxEffect`
- RxJS `repeat` operator
```
--------------------------------
### Using takeUntilDestroyed Operator
Source: https://ngxtension.dev/utilities/dependency-injection/inject-destroy
Illustrates initializing the takeUntilDestroyed operator once and using it later, offering flexibility in its application.
```typescript
@Component({})
export class MyComponent {
private dataService = inject(DataService);
private takeUntilDestroyed$ = takeUntilDestroyed();
ngOnInit() {
this.dataService.getData()
.pipe(this.takeUntilDestroyed$)
.subscribe(...);
}
}
```
--------------------------------
### Provide Global ResizeOptions
Source: https://ngxtension.dev/utilities/directives/resize
Configure `ResizeOptions` globally for the application or a sub-component tree using `provideResizeOptions`. This can be done during application bootstrapping, in an `AppModule`, or for specific routes.
```typescript
// Standalone
bootstrapApplication(App, { providers: [provideResizeOptions(globalOptions)] });
// AppModule
@NgModule({
providers: [provideResizeOptions(globalOptions)],
})
export class AppModule {}
// Route#provider (equivalent to Lazy-load modules)
const route = {
path: 'some-path',
providers: [provideResizeOptions(subTreeGlobalOptions)],
};
```
--------------------------------
### Get entries from SignalSet
Source: https://ngxtension.dev/utilities/signal-primitives/signal-set
Returns an iterator of `[value, value]` pairs for compatibility with the Set API. This operation tracks structure changes.
```typescript
const allEntries = computed(() => Array.from(set.entries()));
```
--------------------------------
### SignalMap get Method
Source: https://ngxtension.dev/utilities/signal-primitives/signal-map
Retrieves the value for a given key. This operation is reactive and tracks changes to the key's value and its existence.
```typescript
const value = computed(() => map.get('key'));
```
--------------------------------
### Todo State Management with SignalMap
Source: https://ngxtension.dev/utilities/signal-primitives/signal-map
Demonstrates how to use SignalMap for managing a collection of todos, including adding, updating, and deleting.
```typescript
class TodoStore {
private todos = new SignalMap();
getTodo = (id: string) => computed(() => this.todos.get(id));
allTodos = computed(() => Array.from(this.todos.values()));
todoCount = computed(() => this.todos.size);
addTodo(todo: Todo) {
this.todos.set(todo.id, todo);
}
updateTodo(id: string, updates: Partial) {
const todo = this.todos.get(id);
if (todo) {
this.todos.set(id, { ...todo, ...updates });
}
}
deleteTodo(id: string) {
this.todos.delete(id);
}
}
```
--------------------------------
### Import and Use RelativeTimeFormatPipe
Source: https://ngxtension.dev/utilities/intl/intl
Import the pipe and add it to your component's imports. This example shows basic usage with a value and unit.
```typescript
import {Component} from "@angular/core";
import {RelativeTimeFormatPipe} from 'ngxtension/intl';
@Component({
selector: 'app-root',
standalone: true,
imports: [RelativeTimeFormatPipe],
template: '
{{ 1 | relativeTimeFormat: \'day\' }}
'
})
```
--------------------------------
### Basic Usage of createInjectionToken
Source: https://ngxtension.dev/utilities/dependency-injection/create-injection-token
Demonstrates the basic usage of `createInjectionToken` to create an injection token for a signal factory. The returned tuple contains functions for injection and provision.
```typescript
function countFactory() {
return signal(0);
}
export const [
injectCount,
/* provideCount */
/* COUNT */
] = createInjectionToken(countFactory);
@Component({})
export class Counter {
count = injectCount(); // WritableSignal
/* count = inject(COUNT); // WritableSignal */
}
```
--------------------------------
### Linking Various Signals to Query Parameters
Source: https://ngxtension.dev/utilities/injectors/linked-query-param
Demonstrates linking model, regular, and input signals to query parameters. Input signals require conversion to a writable signal using `linkedSignal`.
```typescript
import { input, model, linkedSignal, signal } from '@angular/core';
import { linkedQueryParam, paramToNumber } from 'ngxtension/linked-query-param';
export class SearchPageComponent {
// Model signal as source
readonly page = model(1);
readonly pageParam = linkedQueryParam('page', {
source: this.page,
parse: paramToNumber({ defaultValue: 1 }),
});
// If URL has ?page=5, this.page() will be 5
// If URL has no page param, this.page() will be 1 (default)
// Regular signal as source
readonly filterSignal = signal(null);
readonly filterParam = linkedQueryParam('filter', {
source: this.filterSignal,
});
// If URL has ?filter=active, this.filterSignal() will be 'active'
// If URL has no filter param, this.filterSignal() will be null
// Input signal as source -> requires conversion to writable signal
readonly searchInput = input('');
// Convert input to writable signal using linkedSignal
readonly localSearchInput = linkedSignal(() => this.searchInput());
readonly searchParam = linkedQueryParam('search', {
source: this.localSearchInput,
});
}
```
--------------------------------
### takeLatestFrom Usage Example
Source: https://ngxtension.dev/utilities/operators/take-latest-from
Illustrates how to use takeLatestFrom within a class to update data by combining new data with existing data and user information. It waits for both data and user observables to emit before proceeding with the update.
```typescript
class ExampleStore {
private readonly dataSrv = inject(DataService);
private readonly userSrv = inject(UserService);
public readonly updateData = createEffect((_) =>
_.pipe(
takeLatestFrom(() => [this.dataSrv.getData(), this.userSrv.getUser()]),
exhaustMap(([newData, oldData, user]) =>
this.dataSrv.updateData(merge({}, oldData, newData), user),
),
),
);
}
```
--------------------------------
### Basic Usage of injectActiveElement
Source: https://ngxtension.dev/utilities/dom-events/active-element
Create an Observable that emits the active (focused) element. This example demonstrates its use within an Angular component.
```typescript
import { Component } from '@angular/core';
import { injectActiveElement } from 'ngxtension/active-element';
@Component({
standalone: true,
selector: 'app-example',
template: `
{{ (activeElement$ | async)?.innerHTML }}
`,
})
export class ExampleComponent {
activeElement$ = injectActiveElement();
}
```
--------------------------------
### Configuring Non-Root Token with isRoot: false
Source: https://ngxtension.dev/utilities/dependency-injection/create-injection-token
Shows how to create a non-root `InjectionToken` by setting `isRoot: false` in the options. This requires explicit provision using the returned `provideCount` function.
```typescript
export const [injectCount, provideCount] = createInjectionToken(countFactory, {
isRoot: false,
});
@Component({
providers: [provideCount()],
})
export class Counter {
count = injectCount(); // WritableSignal
/* count = inject(COUNT); // WritableSignal */
}
```
--------------------------------
### Inject Route Data as Signal
Source: https://ngxtension.dev/utilities/injectors/inject-route-data
Use injectRouteData to get the current route data as a signal. This is useful for components within the routing context.
```typescript
@Component({
standalone: true,
template: '
{{routeData() | json}}
',
})
class TestComponent {
routeData = injectRouteData();
}
```
--------------------------------
### ListFormatPipe with Style and Locale Parameters
Source: https://ngxtension.dev/utilities/intl/intl
Demonstrates how to pass custom style and locale parameters to the ListFormatPipe. This allows overriding the default locale settings for specific instances.
```html
```
--------------------------------
### Get all query params as a signal
Source: https://ngxtension.dev/utilities/injectors/inject-query-params
Inject all current query parameters as a signal. This signal will update automatically when the query parameters in the URL change.
```typescript
import { injectQueryParams } from 'ngxtension/inject-query-params';
@Component({
template: '
{{queryParams() | json}}
',
})
class TestComponent {
queryParams = injectQueryParams();
}
```
--------------------------------
### Using initialValue with derivedFrom
Source: https://ngxtension.dev/utilities/signals/derived-from
Prevent errors with asynchronous observables by providing an `initialValue` in the options object. This sets the starting value for the resulting Signal.
```typescript
const combined = derivedFrom(
[page$, filters$],
switchMap(([page, filters]) => this.dataService.getArrInfo$(page, filters)),
{ initialValue: [] as Info[] }, // define the initial value of resulting signal
); // inferred ad Signal
```
--------------------------------
### Using an Existing InjectionToken with token Option
Source: https://ngxtension.dev/utilities/dependency-injection/create-injection-token
Shows how to associate an existing `InjectionToken` with the created `injectFn` and `provideFn` using the `token` option. This is useful for hierarchical injection scenarios.
```typescript
export const SERVICE = new InjectionToken('TreeService');
function serviceFactory(parent: TreeService | null) {
/* */
}
export const [injectService, provideService] = createInjectionToken(
serviceFactory,
{
isRoot: false,
deps: [[new Optional(), new SkipSelf(), SERVICE]],
token: SERVICE,
},
);
```
--------------------------------
### Basic RepeatPipe Usage
Source: https://ngxtension.dev/utilities/pipes/repeat
Use the repeat pipe to loop a specific number of times. The pipe generates numbers starting from 0 by default.
```typescript
import { Component } from '@angular/core';
import { RepeatPipe } from 'ngxtension/repeat-pipe';
@Component({
imports: [RepeatPipe],
template: `
@for (i of 3 | repeat; track i) {
{{ i }}
}
`,
})
export class App {}
```
--------------------------------
### Convert Regular Set to SignalSet
Source: https://ngxtension.dev/utilities/signal-primitives/signal-set
Shows how to create a SignalSet instance from a regular JavaScript Set. This allows integrating existing Set data into a reactive context.
```typescript
const regularSet2 = new Set(['x', 'y', 'z']);
const signalSet2 = new SignalSet(Array.from(regularSet2));
```
--------------------------------
### Usage of createSignal and createComputed
Source: https://ngxtension.dev/utilities/signal-primitives/create-signal
Demonstrates how to create a signal with an initial object, log its value using an effect, update the signal's value, and create a computed signal based on the state. Ensure `effect` is imported from your reactive framework.
```typescript
import { createSignal, createComputed } from 'ngxtension/create-signal';
const state = createSignal({ count: 0 });
effect(() => {
// Works as expected
console.log(state.value.count);
});
// Effect will log: 1
state.value = { count: 1 }; // Sets the value
// Effect will log: 1
const double = createComputed(() => state.value.count * 2);
console.log(double.value); // Logs 2
```
--------------------------------
### Configure RelativeTimeFormatPipe Options
Source: https://ngxtension.dev/utilities/intl/intl
Customize the default options for the RelativeTimeFormatPipe using the provideRelativeTimeFormatOptions provider. This example sets numeric to 'auto' and style to 'long'.
```typescript
import {Component} from "@angular/core";
import {RelativeTimeFormatPipe, provideRelativeTimeFormatOptions} from 'ngxtension/intl';
@Component({
selector: 'app-root',
standalone: true,
imports: [RelativeTimeFormatPipe],
providers: [
provideRelativeTimeFormatOptions({
numeric: 'auto',
style: 'long',
})
],
template: '
{{ 1 | relativeTimeFormat: \'day\' }}
'
})
```
--------------------------------
### Import and Use DisplayNamesPipe
Source: https://ngxtension.dev/utilities/intl/intl
Import DisplayNamesPipe and add it to your component's imports. This example shows how to display the localized name of a language code.
```typescript
import {Component} from "@angular/core";
import {DisplayNamesPipe} from 'ngxtension/intl';
@Component({
selector: 'app-root',
standalone: true,
imports: [DisplayNamesPipe],
template: '
{{ 'en' | displayNames: 'language' }}
'
})
```
--------------------------------
### Import and Use ngxtension Utilities
Source: https://ngxtension.dev/
Import and use ngxtension utilities like linkedQueryParam and derivedFrom in your Angular components. This example demonstrates bidirectional query parameter binding and deriving state from multiple signals.
```typescript
import { linkedQueryParam, paramToNumber } from 'ngxtension/linked-query-param';
import { derivedFrom } from 'ngxtension/derived-from';
@Component({
template: `
@for (result of results(); track result.id) {
{{ result.title }}
}
`,
})
export class MyComponent {
readonly searchQuery = linkedQueryParam('search');
readonly pageNumber = linkedQueryParam('page', {
parse: paramToNumber({ defaultValue: 1 }),
});
readonly results = derivedFrom([this.searchQuery], pipe(
switchMap((query) => this.searchService.search(query)),
));
}
```
--------------------------------
### Inject Specific Route Data Value by Key
Source: https://ngxtension.dev/utilities/injectors/inject-route-data
Retrieve the value for a specific key from the route data. This example injects the 'details' key.
```typescript
@Component({
template: `
{{ details().name }}
{{ details().description }}
`,
})
class TestComponent {
details: Signal = injectRouteData('details'); // returns a signal with the value of the details key in route data object
}
```
--------------------------------
### Import hostBinding from Ngxtension
Source: https://ngxtension.dev/utilities/component-utilities/host-binding
Import the hostBinding function from the 'ngxtension/host-binding' module.
```typescript
import { hostBinding } from 'ngxtension/host-binding';
```
--------------------------------
### Transform Route Data with a Function
Source: https://ngxtension.dev/utilities/injectors/inject-route-data
Pass a function to injectRouteData to transform the route data. This example extracts the keys from the route data object.
```typescript
@Component()
class TestComponent {
routeDataKeys = injectRouteData((data) => Object.keys(data)); // returns a signal with the keys of the route data object
}
```
--------------------------------
### Constructor
Source: https://ngxtension.dev/utilities/signal-primitives/signal-set
Creates a new SignalSet instance, optionally initialized with values. Duplicate values are automatically handled.
```APIDOC
## Constructor
### Description
Creates a new `SignalSet` instance, optionally initialized with values. Duplicate values are automatically handled.
### Parameters
#### Path Parameters
- None
#### Query Parameters
- None
#### Request Body
- None
### Parameters
- `values` (readonly T[] | null) - Optional - Array of values to initialize the set.
### Request Example
```typescript
const set = new SignalSet(['a', 'b', 'c']);
```
### Response
- None
### Response Example
- None
```