### Converting RxJS Observable to Angular Signal with toSignal
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_rxjs.md
Demonstrates how to use the `toSignal` utility to convert an RxJS Observable (an interval timer and an HTTP GET request) into read-only signals within an Angular component. It shows handling initial values and displaying signal values in the template.
```TypeScript
import { Component, inject, OnInit } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { HttpClient } from '@angular/common/http';
import { interval, map } from 'rxjs';
interface Post {
id: number;
title: string;
body: string;
}
@Component({
selector: 'app-data-fetcher',
standalone: true,
imports: [], // HttpClientModule needs to be provided in bootstrapApplication or a parent module
template: `
Timer Value: {{ timerValue() ?? 'Waiting for timer...' }}
Post Title: {{ post()?.title }}
{{ post()?.body }}
Loading post...
Error loading post.
`
})
export class DataFetcherComponent {
private http = inject(HttpClient);
// Convert an interval Observable to a signal
timerValue = toSignal(interval(1000)); // Emits undefined initially, then 0, 1, 2...
// Fetch data and convert to signal
postRequest$ = this.http.get('[https://jsonplaceholder.typicode.com/posts/1](https://jsonplaceholder.typicode.com/posts/1)');
post = toSignal(this.postRequest$, { initialValue: null }); // Type Signal
// Example with requireSync (careful, API must be sync)
// dataSync = toSignal(of(123), { requireSync: true }); // Signal
// Example to catch errors
postError = signal(null);
anotherPost = toSignal(
this.http.get('[https://jsonplaceholder.typicode.com/posts/2').pipe](https://jsonplaceholder.typicode.com/posts/2').pipe)(
// tap({ error: (err) => this.postError.set(err) }) // Not ideal for toSignal error handling
),
{ initialValue: null } // `toSignal` will throw if the observable errors.
// Handle errors within the observable or use a more robust pattern.
);
constructor() {
// A more robust way to handle errors with toSignal is often to catch them
// in the observable pipeline and map them to a success/error state.
// Or, if the signal itself should reflect the error state, this needs careful setup.
// The `toSignal` itself doesn't have a built-in error callback for the signal value.
// If the source observable errors, the signal will also error when read.
}
}
```
--------------------------------
### Defining Component Inputs with Angular Signals
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_input.md
This snippet demonstrates how to define component inputs using the `input()` function in Angular. It shows examples of required inputs, optional inputs with default values, inputs with aliases, and inputs with transform functions. It also includes a computed signal based on an input.
```TypeScript
import { Component, input, computed, Signal, InputSignal, effect, signal } from '@angular/core';
@Component({
selector: 'app-user-profile',
standalone: true,
template: `
User Profile
ID: {{ userId() }}
Name: {{ name() }} ({{ nameType() }})
Status: {{ isActive() ? 'Active' : 'Inactive' }}
Transformed Input (alias 'userAge'): {{ age() }}
`
})
export class UserProfileComponent {
// Required input
userId: InputSignal = input.required();
// Optional input with a default value
name: InputSignal = input('Guest');
// Optional input that can be boolean or string, transformed to boolean
isActive: InputSignal = input(false, {
transform: (value: boolean | string) => typeof value === 'string' ? value === '' || value === 'true' : !!value
});
// Input with an alias and a transform function
age: InputSignal = input(0, {
alias: 'userAge',
transform: (value: number | string) => `Approximately ${value} years`
});
nameType: Signal = computed(() => this.name() === 'Guest' ? 'Default User' : 'Registered User');
constructor() {
effect(() => {
console.log(`User ID changed in UserProfileComponent: ${this.userId()}`);
});
}
}
```
--------------------------------
### Converting Angular Signal to RxJS Observable with toObservable
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_rxjs.md
Illustrates the use of the `toObservable` utility to convert a writable signal into an RxJS Observable. The example shows how to pipe RxJS operators like `debounceTime` and `map` onto the resulting observable and subscribe to update another signal.
```TypeScript
import { Component, signal, WritableSignal, OnInit, OnDestroy } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { debounceTime, map, Subscription, tap } from 'rxjs';
@Component({
selector: 'app-signal-to-observable',
standalone: true,
template: `
`
})
export class SignalToObservableComponent implements OnInit, OnDestroy {
searchTerm: WritableSignal = signal('');
debouncedSearchTerm = signal('');
private searchTerm$: Subscription | undefined;
constructor() {
// Convert the searchTerm signal to an Observable
const searchTermObservable = toObservable(this.searchTerm);
this.searchTerm$ = searchTermObservable.pipe(
debounceTime(300), // Wait for 300ms of inactivity
map(term => term.toUpperCase()),
tap(debouncedTerm => console.log('Debounced and uppercased:', debouncedTerm))
).subscribe(processedTerm => {
this.debouncedSearchTerm.set(processedTerm);
});
}
ngOnDestroy(): void {
this.searchTerm$?.unsubscribe();
}
}
```
--------------------------------
### Creating and Updating Writable Signal in Angular Component (TypeScript)
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_intro.md
Demonstrates how to create a writable signal using `signal()` in an Angular component and update its value using the `update()` and `set()` methods. Shows basic signal usage for managing component state.
```TypeScript
import { Component, signal, WritableSignal } from '@angular/core';
@Component({
selector: 'app-counter',
standalone: true,
template: `
Count: {{ count() }}
`
})
export class CounterComponent {
// Create a writable signal with an initial value of 0
count: WritableSignal = signal(0);
increment(): void {
// Update the signal's value based on the current value
this.count.update(current => current + 1);
}
decrement(): void {
this.count.update(current => current - 1);
}
reset(): void {
// Set the signal's value directly
this.count.set(0);
}
}
```
--------------------------------
### Defining Product Selector Component Template (Angular/HTML)
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Defines the HTML template for the `app-product-selector` component. It displays a list of available products with a button to select each one, a button to load more products (simulating source change), and a section to display the currently selected product using `*ngIf`.
```HTML
Available Products:
{{ product.name }} - ${{ product.price }}
Selected Product (Managed by linkedSignal-like concept):
```
--------------------------------
### Angular Component Template HTML
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Defines the HTML structure for the component, displaying product details, a button to clear manual selection, and a log of the selected product.
```html
ID: {{ product.id }}
Name: {{ product.name }}
Price: \${{ product.price }}
No product selected.
Selected Product Log: {{ selectedProductLog() }}
```
--------------------------------
### Creating Product Selector Component (Angular/TypeScript)
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Defines an Angular standalone component named `app-product-selector`. It includes imports for necessary Angular features like `Component`, `signal`, `WritableSignal`, `effect`, and `computed`. It also includes the template definition and likely component logic (though the logic is cut off in the provided text).
```TypeScript
import { Component, signal, WritableSignal, effect, computed } from '@angular/core';
// Hypothetical linkedSignal function import (official import path may vary)
// For this example, as `linkedSignal` might not be directly available in all environments
// without Angular 19 (or its specific preview), we'll demonstrate the concept.
// If Angular 19 is released and you have it, you would import it:
// import { linkedSignal } from '@angular/core';
// --- Conceptual linkedSignal (Illustrative Polyfill/Helper) ---
// This is a simplified conceptual implementation to demonstrate the idea if linkedSignal is not yet available.
// The actual Angular implementation will be more robust and integrated.
@Component({
selector: 'app-product-selector',
standalone: true,
template: `
```
--------------------------------
### Using Angular effect() with Cleanup
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_effect.md
Demonstrates how to use the `effect()` function within an Angular component's constructor to react to signal changes. Includes using `runInInjectionContext` for automatic cleanup and the `onCleanup` callback for manual resource management like timers.
```TypeScript
import { Component, signal, effect, WritableSignal, Injector, runInInjectionContext } from '@angular/core';
@Component({
selector: 'app-logger',
standalone: true,
template: `
Value:
`
})
export class LoggerComponent {
data: WritableSignal = signal('initial value');
constructor(private injector: Injector) {
// It's common to run effects within an injection context (e.g., constructor)
// so they are automatically cleaned up when the component is destroyed.
runInInjectionContext(this.injector, () => {
effect((onCleanup) => {
const currentValue = this.data();
console.log(`Data changed to: ${currentValue}`);
const timer = setTimeout(() => {
console.log(`Effect side-task for: ${currentValue}`);
}, 1000);
onCleanup(() => {
clearTimeout(timer);
console.log(`Cleaning up effect for old value before re-run or destroy.`);
});
});
});
}
}
```
--------------------------------
### Defining linkedSignal with Object Config - Angular
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Hypothetical alternative syntax for defining a `linkedSignal` using an object configuration, explicitly specifying the source signal (`this.books`) and the computation function (`computation`).
```TypeScript
selectedBook = linkedSignal({ source: this.books, computation: (allBooks) => allBooks[0] });
```
--------------------------------
### Angular Component loadMoreProducts Method TypeScript
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Adds a new product to the `availableProducts` signal, demonstrating how updating the source signal triggers the derivation logic for `selectedProduct` via an effect.
```typescript
loadMoreProducts(): void {
this.availableProducts.update(currentProducts => [
...currentProducts,
{ id: Date.now(), name: `New Gadget ${currentProducts.length + 1}`, price: Math.floor(Math.random() * 100) + 20 },
]);
// When availableProducts changes, the effect linked to selectedProduct should
// re-run the derivation logic, potentially updating selectedProduct to the new first item.
}
```
--------------------------------
### Angular Component Constructor Signal Logic TypeScript
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Initializes the `selectedProduct` signal and sets up effects. One effect re-derives `selectedProduct` when `availableProducts` changes, and another logs the current value of `selectedProduct`.
```typescript
constructor() {
// Initialize selectedProduct using the conceptual helper
// This attempts to mimic the behavior: derived but settable.
// The `computation` function derives the value.
// `sources` tells our conceptual helper which signals should trigger re-computation.
const computation = () => {
console.log('Derivation logic for selectedProduct running...');
const products = this.availableProducts();
return products.length > 0 ? products[0] : undefined;
};
// This is where the official `linkedSignal` would be used.
// For now, using the conceptual helper:
this.selectedProduct = signal(computation()); // Initial value
// Effect to re-run computation if `availableProducts` changes
effect(() => {
const newDerivedValue = computation();
// Only set if it's different to avoid unnecessary updates if the value is complex
// or to allow a manual override to persist until the next actual derived change.
// The precise interaction here is key to how `linkedSignal` would behave.
// A simple approach for this conceptual example:
this.selectedProduct.set(newDerivedValue);
console.log('Source (availableProducts) changed, selectedProduct re-derived.');
}, { allowSignalWrites: true }); // allowSignalWrites for the .set inside effect
// Effect to log changes to the selected product
effect(() => {
const product = this.selectedProduct();
const logMsg = product ? `Selected: ${product.name}` : 'Selection cleared';
this.selectedProductLog.set(logMsg);
console.log(logMsg);
});
}
```
--------------------------------
### Implementing Conceptual linkedSignal Helper Function (Angular/TypeScript)
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
This is a simplified, illustrative implementation of a function that mimics the behavior of a linkedSignal. It takes a computation function and source signals, creates an internal writable signal, and uses an effect to update the internal signal when sources change. It returns the internal signal, allowing direct writes while also reacting to source changes. Note: This is a conceptual helper, not the official Angular implementation.
```TypeScript
function conceptualLinkedSignal(
computation: () => T,
sources: WritableSignal[] // Simplified: list of signals that trigger re-computation
): WritableSignal {
const internalSignal = signal(computation());
// Effect to update the internalSignal when any source changes
effect(() => {
internalSignal.set(computation());
}, { allowSignalWrites: true }); // AllowSignalWrites needed if computation itself writes to signals (not typical for computation part)
// Return a WritableSignal that allows external set/update
// and is updated by the effect.
// A real linkedSignal would likely be a primitive with more optimized tracking.
return internalSignal; // In a real scenario, the returned signal would have special properties.
}
```
--------------------------------
### Defining Product Interface (Angular/TypeScript)
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Defines a simple TypeScript interface for a Product object, including properties for id, name, and price. This interface is used within the component to type the product data.
```TypeScript
interface Product {
id: number;
name: string;
price: number;
}
```
--------------------------------
### Defining Angular Signal Output with output() - TypeScript
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_output.md
This snippet demonstrates how to define a component output using the signal-based output() function. It shows how to type the output and how to emit values using the emit() method within a component class.
```TypeScript
import { Component, output, OutputEmitterRef, signal } from '@angular/core';
@Component({
selector: 'app-action-button',
standalone: true,
template: `
`
})
export class ActionButtonComponent {
// Define an output that emits a string payload
action: OutputEmitterRef = output();
// Can also use input() for buttonText
buttonText = signal('Click Me');
handleClick(): void {
const timestamp = new Date().toLocaleTimeString();
this.action.emit(`Button clicked at ${timestamp}`);
}
}
```
--------------------------------
### Using Angular Signal Output in Parent Component - TypeScript
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_output.md
This snippet shows how a parent component consumes the signal output defined by a child component. It demonstrates listening to the output event in the template using the standard event binding syntax and handling the emitted payload in a component method.
```TypeScript
// Parent component usage:
@Component({
selector: 'app-action-container',
standalone: true,
imports: [ActionButtonComponent],
template: `
Last action: {{ lastAction() }}
`
})
export class ActionContainerComponent {
lastAction = signal('No action yet.');
onAction(payload: string): void {
this.lastAction.set(payload);
console.log('Action received from child:', payload);
}
}
```
--------------------------------
### Angular Component Styles CSS
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Provides basic CSS styling for the component's elements like horizontal rules, lists, and list items.
```css
hr { margin: 20px 0; }
ul { list-style: none; padding: 0; }
li { margin-bottom: 8px; padding: 5px; background-color: #f4f4f4; border-radius: 3px; }
```
--------------------------------
### Using a Component with Signal Inputs in Angular
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_input.md
This snippet shows a parent component consuming the `UserProfileComponent` which uses signal inputs. It demonstrates how to bind values to signal inputs using property binding (`[]`) and attribute binding, including using the defined alias (`userAge`). It also includes a button to change a signal that is bound to an input.
```TypeScript
// Parent component usage:
@Component({
selector: 'app-parent-for-profile',
standalone: true,
imports: [UserProfileComponent],
template: `
`
})
export class ParentForProfileComponent {
currentUserId = signal('user-001');
changeUser() {
this.currentUserId.set('user-xyz-' + Math.random().toString(16).slice(2));
}
}
```
--------------------------------
### Angular Component Signal Declarations TypeScript
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Declares the component's signals: `availableProducts` (the source), `selectedProduct` (the conceptual linked signal), and `selectedProductLog` (for logging changes).
```typescript
availableProducts: WritableSignal = signal([
{ id: 1, name: 'Super Keyboard', price: 75 },
{ id: 2, name: 'Ergonomic Mouse', price: 45 },
]);
// Using the conceptualLinkedSignal for demonstration.
// With official Angular 19, this would be:
// selectedProduct: WritableSignal = linkedSignal(
// () => this.availableProducts()[0] // The derivation function
// // Angular's linkedSignal might automatically track dependencies or have a way to specify them.
// );
// For our conceptual version, we pass the source explicitly.
selectedProduct: WritableSignal;
selectedProductLog = signal('');
```
--------------------------------
### Defining linkedSignal with Lambda - Angular
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Hypothetical syntax for defining a `linkedSignal` where the derived value is computed using a simple lambda function that accesses the first element of a source signal (`this.books()`).
```TypeScript
selectedBook = linkedSignal(() => this.books()[0]);
```
--------------------------------
### Using Angular model() for Two-Way Binding in Parent Component
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_sigal_model.md
This snippet shows how a parent component binds to a child component's model signal using the [(modelName)] syntax. It demonstrates how the parent can read the current value and update the signal.
```TypeScript
// Parent component usage:
@Component({
selector: 'app-form',
standalone: true,
imports: [CustomInputComponent],
template: `
Current Name in Parent: {{ name() }}
`
})
export class FormComponent {
name: WritableSignal = signal('Initial Name');
setNameInParent() {
this.name.set('Set by Parent');
}
}
```
--------------------------------
### Implementing Two-Way Binding with model() in Angular Component
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_sigal_model.md
This snippet demonstrates how to use model.required() for a mandatory two-way bound input and model() for an optional input. It shows how the component updates the model signal internally via the set() method.
```TypeScript
import { Component, model, ModelSignal } from '@angular/core';
@Component({
selector: 'app-custom-input',
standalone: true,
template: `
`
})
export class CustomInputComponent {
// Required model input
value: ModelSignal = model.required();
// Optional input for label
label: ModelSignal = model(); // Can also use input() here if not two-way bound
onInput(event: Event): void {
const target = event.target as HTMLInputElement;
this.value.set(target.value); // Update the model signal
}
clearValue(): void {
this.value.set('');
}
}
```
--------------------------------
### Angular Component manuallySelectProduct Method TypeScript
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Allows directly setting the value of the `selectedProduct` signal, overriding the value derived from `availableProducts`.
```typescript
manuallySelectProduct(product: Product): void {
console.log(`Manually setting selectedProduct to: ${product.name}`);
this.selectedProduct.set(product);
// Now selectedProduct holds the manually selected product.
// If `loadMoreProducts` is called, the derivation logic will run again.
// The behavior of `linkedSignal` would define if this manual set is sticky
// or if the derivation always wins on source change.
// Typically, the derivation would re-evaluate based on the new source.
}
```
--------------------------------
### Creating Computed Signals in Angular
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_computed.md
This snippet demonstrates how to use Angular's signal() and computed() functions within a component. It defines writable signals for first and last names and uses computed signals to derive the full name and a boolean indicating if the full name is long. The template shows how these signals are used and automatically update.
```TypeScript
import { Component, signal, computed, Signal, WritableSignal } from '@angular/core';
@Component({
selector: 'app-derived-values',
standalone: true,
template: `
First Name:
Last Name:
Full Name: {{ fullName() }}
Is Full Name Long?: {{ isFullNameLong() ? 'Yes' : 'No' }}
`
})
export class DerivedValuesComponent {
firstName: WritableSignal = signal('John');
lastName: WritableSignal = signal('Doe');
// Create a computed signal for the full name
fullName: Signal = computed(() => `${this.firstName()} ${this.lastName()}`);
// Create another computed signal based on the fullName signal
isFullNameLong: Signal = computed(() => this.fullName().length > 10);
}
```
--------------------------------
### Angular Component clearSelection Method TypeScript
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_linkedSignal.md
Resets the `selectedProduct` signal by re-applying the original derivation logic, effectively clearing any manual selection and reverting to the derived value.
```typescript
clearSelection(): void {
console.log('Clearing manual selection, letting derivation logic take over.');
// To truly reset to derived, you might re-run the derivation or set to undefined
// and let the effect pick it up. Or, if linkedSignal supports it, a specific reset method.
// For this example, setting to undefined triggers the derivation in a way.
// A more direct way would be to re-apply the original derivation:
const products = this.availableProducts();
this.selectedProduct.set(products.length > 0 ? products[0] : undefined);
}
```
--------------------------------
### Using untracked() in an Angular Effect
Source: https://github.com/binsondev/angular_signal_doc/blob/main/angular_signal_untracked.md
This Angular component demonstrates how to use the untracked() function within an effect. The effect tracks changes to 'triggerValue' but reads 'observedValue' using untracked(), preventing the effect from re-running when 'observedValue' changes. It requires Angular's signals feature and dependency injection for effects.
```TypeScript
import { Component, signal, effect, untracked, WritableSignal, Injector, runInInjectionContext } from '@angular/core';
@Component({
selector: 'app-untracked-example',
standalone: true,
template: `
Trigger Value:
Observed Value:
Effect Log: {{ effectLog() }}
`
})
export class UntrackedExampleComponent {
triggerValue: WritableSignal = signal(0);
observedValue: WritableSignal = signal('hello');
effectLog: WritableSignal = signal('');
constructor(private injector: Injector) {
runInInjectionContext(this.injector, () => {
effect(() => {
// This effect will ONLY re-run when `triggerValue` changes.
// Changes to `observedValue` will NOT trigger this effect.
const currentTrigger = this.triggerValue();
const currentObserved = untracked(() => this.observedValue()); // Read without tracking
const logMessage = `Effect ran. Trigger: ${currentTrigger}, Observed (untracked): ${currentObserved}`;
console.log(logMessage);
this.effectLog.set(logMessage);
});
});
}
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.