Skip to content

docs: add guidance against calling methods in templates - #71941

Open
JeevanMahesha wants to merge 1 commit into
angular:mainfrom
JeevanMahesha:docs/skill-avoid-function-calls-in-templates
Open

JeevanMahesha wants to merge 1 commit into
angular:mainfrom
JeevanMahesha:docs/skill-avoid-function-calls-in-templates

Conversation

@JeevanMahesha

@JeevanMahesha JeevanMahesha commented Nov 11, 2026 •

Copy link
Copy Markdown

Why

Several reports on #70132 show AI coding agents using the angular-developer skill writing method calls inside template expressions, for example @for (_ of items(count); track $index), where items() builds a new array on every check. The skill had no guidance on this, so agents had nothing telling them to avoid it.

There is no maintainer consensus that every function call in a template is wrong. Signal reads are function calls, and with OnPush and zoneless a cheap call can be fine. So the guidance targets methods that take arguments or return new arrays/objects, and explicitly allows signal reads and trivial lookups.

What

  • SKILL.md: a short rule in the Components section, which agents read whenever they use the skill, linking to the details.
  • references/components.md: a new "Avoiding function calls in templates" section that explains why it matters, lists alternatives (computed(), a pure pipe, a child component), and shows a before/after for the nested @for case from the issue. A computed() cannot take arguments, so the example derives the whole nested structure once.

Markdown-only change, so no automated tests apply. This is guidance for agents and has not been evaluated against agent output, so it is linked to the issue rather than closing it.

Related to #70132. Supersedes #70168, which was closed because its author had not signed the CLA.

@angular-robot angular-robot Bot added the area: docs Related to the documentation label Nov 11, 2026
@pullapprove
pullapprove Bot requested a review from kirjs November 11, 2026 05:31
@ngbot ngbot Bot added this to the Backlog milestone Nov 11, 2026
AI coding agents using the angular-developer skill were observed calling
plain methods inside @for/@if template expressions, for example
items(count) returning a new array on every check. The skill had no
guidance on this.

Add a short rule to SKILL.md and a fuller section to components.md that
recommends computed(), a pure pipe or a child component instead, with an
example for the nested @for case. Signal reads and trivial lookups stay
allowed.

Related to angular#70132
@JeevanMahesha
JeevanMahesha force-pushed the docs/skill-avoid-function-calls-in-templates branch from fb3b201 to 6d7b81f Compare November 11, 2026 05:37
@JeevanMahesha JeevanMahesha changed the title docs: warn against non-memoized function calls in templates docs: add guidance against calling methods in templates Nov 11, 2026
Comment on lines +123 to +142
```ts
// Avoid: items() runs again for every group on every check.
groups = computed(() => [this.count(), 1, 1]);
items(count: number) {
return Array(count);
}
```

```html
@for (count of groups(); track $index) { @for (_ of items(count); track $index) { ... } }
```

```ts
// Prefer: derive the nested data once.
groups = computed(() => [this.count(), 1, 1].map((n) => Array.from({length: n}, (_, i) => i)));
```

```html
@for (group of groups(); track $index) { @for (item of group; track item) { ... } }
```

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.

I don't think there is much value in those examples

@@ -108,6 +108,39 @@ The `@for` block iterates over collections. The `track` expression is **required

**Implicit Variables**: `$index`, `$count`, `$first`, `$last`, `$even`, `$odd`.

### Avoiding function calls in templates

Do not call component methods from template expressions, especially methods that take arguments or build a new array or object (e.g. `@for (x of getItems(count))`, `{{ formatDate(item.date) }}`). A method is re-run every time the component's template is checked, which happens on every change when the component is dirty (OnPush and zoneless reduce how often, but do not make the call cached). Methods that return a new array or object also give `@for` a new collection on every run.

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.

I think there is little value here too in giving examples.

And as mentionned in the issue, calling an method is not an issue per se.
What agent need to be careful is invoking expensive functions on every change detection cycle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: docs Related to the documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants