Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
docs: fix inaccurate statements and broken examples across adev
Fix code examples that don't compile or fail at runtime, wrong API
names, and statements of defaults or behavior that no longer match the
source, across the forms, signals, http, routing, DI, components,
testing, CLI, reference, ecosystem and tutorial pages.
  • Loading branch information
GabeSilvaDev authored and NothingEverHappens committed Oct 2, 2026
commit 9230181b327e7dd209fca888fcc692769389711d
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Change detection is sufficiently fast for most applications. However, when an ap

OnPush is the default change detection strategy in Angular (since v22). It instructs Angular to run change detection for a component subtree **only** when:

- The root component of the subtree receives new inputs as the result of a template binding. Angular compares the current and past value of the input with `==`.
- The root component of the subtree receives new inputs as the result of a template binding. Angular compares the current and past value of the input with `Object.is`.
- Angular handles an event _(for example using event binding, output binding, or `@HostListener` )_ in the subtree's root component or any of its children whether they are using OnPush change detection or not.

## Common change detection scenarios
Expand Down
2 changes: 1 addition & 1 deletion adev/src/content/ecosystem/rxjs-interop/output-interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

TIP: This guide assumes you're familiar with [component and directive outputs](guide/components/outputs).

The `@angular/rxjs-interop` package offers two APIs related to component and directive outputs.
The `@angular/core/rxjs-interop` package offers two APIs related to component and directive outputs.

## Creating an output based on an RxJs Observable

Expand Down
2 changes: 1 addition & 1 deletion adev/src/content/ecosystem/rxjs-interop/signals-interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Here, only the last value (3) will be logged.

## Using `rxResource` for async data

Angular's [`resource` function](/guide/signals/resource) gives you a way to incorporate async data into your application's signal-based code. Building on top of this pattern, `rxResource` lets you define a resource where the source of your data is defined in terms of an RxJS `Observable`. Instead of accepting a `loader` function, `rxResource` accepts a `stream` function that accepts an RxJS `Observable`.
Angular's [`resource` function](/guide/signals/resource) gives you a way to incorporate async data into your application's signal-based code. Building on top of this pattern, `rxResource` lets you define a resource where the source of your data is defined in terms of an RxJS `Observable`. Instead of accepting a `loader` function, `rxResource` accepts a `stream` function that returns an RxJS `Observable`.

```typescript
import {Component, inject} from '@angular/core';
Expand Down
17 changes: 8 additions & 9 deletions adev/src/content/ecosystem/service-workers/communications.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ The `SwUpdate` service supports three separate operations:

### Version updates

The `versionUpdates` is an `Observable` property of `SwUpdate` and emits five event types:

| Event types | Details |
| :------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `VersionDetectedEvent` | Emitted when the service worker has detected a new version of the app on the server and is about to start downloading it. |
| `NoNewVersionDetectedEvent` | Emitted when the service worker has checked the version of the app on the server and did not find a new version. |
| `VersionReadyEvent` | Emitted when a new version of the app is available to be activated by clients. It may be used to notify the user of an available update or prompt them to refresh the page. |
| `VersionInstallationFailedEvent` | Emitted when the installation of a new version failed. It may be used for logging/monitoring purposes. |
| `VersionFailedEvent` | Emitted when a version encounters a critical failure (such as broken hash errors) that affects all clients using that version. Provides error details for debugging and transparency. |
The `versionUpdates` is an `Observable` property of `SwUpdate` and emits four event types:

| Event types | Details |
| :------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `VersionDetectedEvent` | Emitted when the service worker has detected a new version of the app on the server and is about to start downloading it. |
| `NoNewVersionDetectedEvent` | Emitted when the service worker has checked the version of the app on the server and did not find a new version. |
| `VersionReadyEvent` | Emitted when a new version of the app is available to be activated by clients. It may be used to notify the user of an available update or prompt them to refresh the page. |
| `VersionInstallationFailedEvent` | Emitted when the installation of a new version failed. It may be used for logging/monitoring purposes. |

<docs-code header="log-update.service.ts" path="adev/src/content/examples/service-worker-getting-started/src/app/log-update.service.ts" region="sw-update"/>

Expand Down
2 changes: 1 addition & 1 deletion adev/src/content/ecosystem/service-workers/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ The ServiceWorker redirects navigation requests that don't match any `asset` or
A request is considered to be a navigation request if:

- Its [method](https://developer.mozilla.org/docs/Web/API/Request/method) is `GET`
- Its [mode](https://developer.mozilla.org/docs/Web/API/Request/mode) is `navigation`
- Its [mode](https://developer.mozilla.org/docs/Web/API/Request/mode) is `navigate`
- It accepts a `text/html` response as determined by the value of the `Accept` header
- Its URL matches the following criteria:
- The URL must not contain a file extension (that is, a `.`) in the last path segment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {Component, input} from '@angular/core';
'aria-valuemax': '100',

// Binding that updates the current value of the progressbar.
'[attr.aria-valuenow]': 'value',
'[attr.aria-valuenow]': 'value()',
},
})
export class ExampleProgressbarComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ export class LogUpdateService {
case 'VERSION_INSTALLATION_FAILED':
console.log(`Failed to install app version '${evt.version.hash}': ${evt.error}`);
break;
case 'VERSION_FAILED':
console.log(`Version '${evt.version.hash}' failed with error: ${evt.error}`);
break;
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
export class ComponentWithCustomElements { }
```

Angular does not support any other schemas at this time.
Angular also provides `NO_ERRORS_SCHEMA`, which allows any element and any property.
2 changes: 1 addition & 1 deletion adev/src/content/guide/components/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export class UserProfile {}

If the query does not find a result, its value is `undefined`. This may occur if the target element is absent or hidden by `@if`. Angular keeps the result of `contentChild` up to date as your application state changes.

By default, content queries find only _direct_ children of the component and do not traverse into descendants.
By default, `contentChild` queries traverse into descendants, while `contentChildren` queries find only _direct_ children. See [Content descendants](#content-descendants).

You can also query for multiple results with the `contentChildren` function.

Expand Down
20 changes: 10 additions & 10 deletions adev/src/content/guide/di/debugging-and-troubleshooting-di.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Each component gets its own `UserClient` instance. Changes in one component don'
**Solution:** Use `@Service` for singletons.

```ts {prefer, header: 'Root-level singleton'}
import {Injectable} from '@angular/core';
import {Service} from '@angular/core';

@Service()
export class UserClient {
Expand Down Expand Up @@ -250,7 +250,7 @@ export class UserProfile {
Use `runInInjectionContext()` when you need to enable **other code** to call `inject()`. This is useful when accepting callbacks that might use dependency injection:

```angular-ts
import {Component, inject, Injector, input} from '@angular/core';
import {Component, inject, Injector, input, runInInjectionContext} from '@angular/core';

@Component({
selector: 'app-data-loader',
Expand All @@ -264,13 +264,13 @@ export class DataLoader {
const callback = this.onLoad();
if (callback) {
// Enable the callback to use inject()
this.injector.runInInjectionContext(callback);
runInInjectionContext(this.injector, callback);
}
}
}
```

The `runInInjectionContext()` method creates a temporary injection context, allowing code inside the callback to call `inject()`.
The `runInInjectionContext()` function creates a temporary injection context, allowing code inside the callback to call `inject()`.

IMPORTANT: Always capture dependencies at the class level when possible. Use `injector.get()` for simple deferred retrieval, and `runInInjectionContext()` only when external code needs to call `inject()`.

Expand Down Expand Up @@ -671,7 +671,7 @@ This section provides detailed information about specific Angular DI error codes

### NullInjectorError: No provider for [Service]

**Error code:** None (displayed as `NullInjectorError`)
**Error code:** [NG0201](errors/NG0201)

This error occurs when Angular cannot find a provider for a token in the injector hierarchy. The error message includes a dependency path showing where the injection was attempted.

Expand Down Expand Up @@ -855,12 +855,12 @@ Angular allows `inject()` in these locations:
})
export class UserProfile {
private userService: UserClient;
user: ReturnType<UserClient['getUser']>;

constructor() {
this.userService = inject(UserClient); // Valid
this.user = this.userService.getUser();
}

user = this.userService.getUser();
}
```

Expand All @@ -882,7 +882,7 @@ Angular allows `inject()` in these locations:
4. **Inside runInInjectionContext()**

```angular-ts
import {Component, inject, Injector} from '@angular/core';
import {Component, inject, Injector, runInInjectionContext} from '@angular/core';
import {UserClient} from './user-client';

@Component({
Expand All @@ -893,7 +893,7 @@ Angular allows `inject()` in these locations:
private injector = inject(Injector);

loadUser() {
this.injector.runInInjectionContext(() => {
runInInjectionContext(this.injector, () => {
const userService = inject(UserClient); // Valid
console.log(userService.getUser());
});
Expand Down Expand Up @@ -934,7 +934,7 @@ private userService = inject(UserClient) // Capture at class level
private injector = inject(Injector)

someCallback() {
this.injector.runInInjectionContext(() => {
runInInjectionContext(this.injector, () => {
const service = inject(MyClient)
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ bootstrapApplication(App, appConfig);
The `bootstrapApplication()` method creates a child injector of the platform injector which is configured by the `ApplicationConfig` instance.
This is the `root` `EnvironmentInjector`.

The `platformBrowserDynamic()` method creates an injector configured by a `PlatformModule`, which contains platform-specific dependencies.
The `bootstrapApplication()` method also creates (or reuses) the platform injector, which contains platform-specific dependencies.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The `bootstrapApplication()` method also creates (or reuses) the platform injector, which contains platform-specific dependencies.
The `bootstrapApplication()` function also creates (or reuses) the platform injector, which contains platform-specific dependencies.

This allows multiple applications to share a platform configuration.
For example, a browser has only one URL bar, no matter how many applications you have running.
You can configure additional platform-specific providers at the platform level by supplying `extraProviders` using the `platformBrowser()` function.
Expand Down
2 changes: 1 addition & 1 deletion adev/src/content/guide/elements.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Component properties and logic map directly into HTML attributes and the browser
- The creation API parses the component looking for input properties, and defines corresponding attributes for the custom element.
It transforms the property names to make them compatible with custom elements, which do not recognize case distinctions.
The resulting attribute names use dash-separated lowercase.
For example, for a component with `inputProp = input({alias: 'myInputProp'})`, the corresponding custom element defines an attribute `my-input-prop`.
For example, for a component with `inputProp = input('', {alias: 'myInputProp'})`, the corresponding custom element defines an attribute `my-input-prop`.

- Component outputs are dispatched as HTML [Custom Events](https://developer.mozilla.org/docs/Web/API/CustomEvent), with the name of the custom event matching the output name.
For example, for a component with `valueChanged = output()`, the corresponding custom element dispatches events with the name "valueChanged", and the emitted data is stored on the event's `detail` property.
Expand Down
2 changes: 1 addition & 1 deletion adev/src/content/guide/forms/form-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ Use [`setValidators`](api/forms/AbstractControl#setValidators) to replace all ex
toggleStrictNameValidation(isStrict: boolean) {
const nameControl = this.profileForm.get('name');

if (enable) {
if (isStrict) {
// Set strict validation rules
nameControl.setValidators([
Validators.required,
Expand Down
4 changes: 2 additions & 2 deletions adev/src/content/guide/forms/reactive-forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ In the template, each control is displayed as a separate input field.

<docs-step title="Display the form array in the template">

To attach the aliases from your form model, you must add it to the template. Similar to the `formGroupName` input provided by `FormGroupNameDirective`, `formArrayName` binds communication from the form array instance to the template with `FormArrayNameDirective`.
To attach the aliases from your form model, you must add it to the template. Similar to the `formGroupName` input provided by `FormGroupName`, `formArrayName` binds communication from the form array instance to the template with `FormArrayName`.

Add the following template HTML after the `<div>` closing the `formGroupName` element.

Expand Down Expand Up @@ -520,7 +520,7 @@ control.events
**Before**

```ts
import {combineLatest} from 'rxjs/operators';
import {combineLatest} from 'rxjs';

combineLatest([control.valueChanges, control.statusChanges]).subscribe(([value, status]) => {
/* ... */
Expand Down
10 changes: 5 additions & 5 deletions adev/src/content/guide/forms/signals/async-operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,19 +211,19 @@ onError: (error) => {

### HTTP options

Customize the HTTP request with the `options` parameter:
Customize the HTTP request by returning an `HttpResourceRequest` object from the `request` function:

```ts
import {HttpHeaders} from '@angular/common/http';

validateHttp(schemaPath.field, {
request: ({value}) => `/api/validate?value=${value()}`,
options: {
request: ({value}) => ({
url: `/api/validate?value=${value()}`,
headers: new HttpHeaders({
Authorization: 'Bearer token',
}),
timeout: 5000,
},
}),
onSuccess: (response: {valid: boolean}) =>
response.valid
? null
Expand Down Expand Up @@ -597,7 +597,7 @@ When async validation runs, the field's `pending()` signal returns `true`. Durin
- `valid()` returns `false`
- `invalid()` returns `false`
- `errors()` returns an empty array
- `submit()` waits for validation to complete
- `submit()` does not wait for it; by default the `action` runs anyway (see [`ignoreValidators`](guide/forms/signals/form-submission#controlling-validation-gating-with-ignorevalidators))

Show the pending state in your template to provide feedback:

Expand Down
2 changes: 1 addition & 1 deletion adev/src/content/guide/forms/signals/custom-controls.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ Control whether users can interact with your field:
| `readonly` | Whether the field is readonly (visible but not editable) |
| `hidden` | Whether the field is hidden from view |

NOTE: `disabledReasons` is an array of `DisabledReason` objects. Each object has a `field` property (reference to the field tree) and an optional `message` property. Access the message via `reason.message`.
NOTE: `disabledReasons` is an array of `DisabledReason` objects. Each object has a `fieldTree` property (reference to the field tree) and an optional `message` property. Access the message via `reason.message`.

#### Validation constraints

Expand Down
2 changes: 1 addition & 1 deletion adev/src/content/guide/forms/signals/form-submission.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ submission: {

## Concurrent submissions

When a submission is in progress, subsequent calls to `submit()` for the same form or any of its parents return `false` immediately without running the action. This prevents duplicate submissions and side effects if a user triggers the submit action multiple times quickly.
When a submission is in progress, subsequent calls to `submit()` for the same form or any of its descendants return `false` immediately without running the action. This prevents duplicate submissions and side effects if a user triggers the submit action multiple times quickly.

## Next steps

Expand Down
2 changes: 1 addition & 1 deletion adev/src/content/guide/forms/signals/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ import {BasicInput} from './basic-input';
</form>
<p>Text: {{ reactiveFormGroup.value.reactiveControlName }}</p>
`,
imports: [ReactiveFormsModule],
imports: [ReactiveFormsModule, BasicInput],
})
export class ExampleComponent {
readonly reactiveFormGroup = new FormGroup({
Expand Down
4 changes: 2 additions & 2 deletions adev/src/content/guide/forms/signals/validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ The validator function receives a `FieldContext` object with:
| --------------- | ---------- | ------------------------------------------- |
| `value` | Signal | Signal containing the current field value |
| `state` | FieldState | The field state reference |
| `field` | FieldTree | The field tree reference |
| `fieldTree` | FieldTree | The field tree reference |
| `valueOf()` | Method | Get the value of another field by path |
| `stateOf()` | Method | Get the state of another field by path |
| `fieldTreeOf()` | Method | Get the field tree of another field by path |
Expand Down Expand Up @@ -668,7 +668,7 @@ import {Component, signal} from '@angular/core';
import {form, FormField, required, validateHttp} from '@angular/forms/signals';

@Component({
selector: 'app-username-form',|
selector: 'app-username-form',
imports: [FormField],
template: `
<form novalidate>
Expand Down
6 changes: 3 additions & 3 deletions adev/src/content/guide/http/interceptors.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,9 @@ export function authRedirectInterceptor(

## Working with response types

When `HttpClient` uses the fetch backend, responses include a `type` property that indicates how the browser handled the response based on CORS policies and request mode. This property aligns with the native Fetch API specification and provides valuable insights for debugging CORS issues and understanding response accessibility.
When `HttpClient` uses the fetch backend, responses include a `responseType` property that indicates how the browser handled the response based on CORS policies and request mode. This property aligns with the native Fetch API specification and provides valuable insights for debugging CORS issues and understanding response accessibility.

The response `type` property can have the following values:
The response `responseType` property can have the following values:

- `'basic'` - Same-origin response with all headers accessible
- `'cors'` - Cross-origin response with CORS headers properly configured
Expand All @@ -233,7 +233,7 @@ export function responseTypeInterceptor(
next: HttpHandlerFn,
): Observable<HttpEvent<unknown>> {
return next(req).pipe(
map((event) => {
tap((event) => {
if (event.type === HttpEventType.Response) {
// Handle different response types appropriately
switch (event.responseType) {
Expand Down
Loading
Loading