<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cookbook on AngularTS</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/</link><description>Recent content in Cookbook on AngularTS</description><generator>Hugo</generator><language>en</language><atom:link href="https://angular-wave.github.io/angular.ts/docs/cookbook/index.xml" rel="self" type="application/rss+xml"/><item><title>Debug a running application</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/inspect-running-application/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/inspect-running-application/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A page is running, but you do not know which state, controller, or service owns
the DOM you are looking at. You want to inspect it before changing code.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Run a development build with AngularTS debugging helpers available. Open the
page and browser DevTools; no source changes are required for the first
inspection.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Open the browser&amp;rsquo;s &lt;strong>Elements&lt;/strong> panel and select the element you want to
inspect. The DevTools console exposes that element as &lt;code>$0&lt;/code>.&lt;/p></description></item><item><title>Select an element with ng-el</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/select-elements/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/select-elements/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Your controller needs a native element so it can focus an input, draw on a
canvas, measure layout, or call another browser API.&lt;/p>
&lt;p>Do not search the document with &lt;code>querySelector&lt;/code>. Declare the element you need
and let AngularTS wire it to your state.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use this inside a compiled scope or controller that owns the element. Keep
document-wide elements in a service rather than attaching unrelated DOM to a
local scope.&lt;/p></description></item><item><title>Pass server data with ng-init or ng-setter</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/server-data/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/server-data/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server already knows values that the browser needs, such as the current
locale, a record ID, or the initial result count. You want AngularTS to use
those values without making another request.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server template must safely serialize and HTML-encode the initial value.
Decide whether the value is fixed at compilation or can change when another
system replaces element content.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Render an &lt;code>ng-init&lt;/code> expression with the page:&lt;/p></description></item><item><title>Update text, classes, styles, and visibility</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/update-dom/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/update-dom/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>State changes, and the page must update without finding elements or assigning
DOM properties by hand.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Identify the scope or controller property that owns the visible result.
User-provided text must remain text unless it has passed an explicit
trusted-HTML policy.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Bind each part of the element to scope state:&lt;/p>
&lt;!-- tested-by: src/binding.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span> &lt;span style="color:#c4a000">ng-controller&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;ProductController as product&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h2&lt;/span> &lt;span style="color:#c4a000">ng-bind&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;product.name&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h2&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-class&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{ featured: product.featured, soldOut: !product.inStock }&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-style&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{ opacity: product.inStock ? 1 : 0.5 }&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {{ product.price | currency }}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-show&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;product.inStock&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Available now&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-hide&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;product.inStock&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Out of stock&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;product.featured = !product.featured&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Toggle featured
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Change the model, not the element:&lt;/p></description></item><item><title>Replace part of the page from state</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/replace-dom/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/replace-dom/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A page has mutually exclusive steps or an expensive section that should not
exist while it is inactive.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Decide whether hidden DOM state must survive. Structural directives destroy
branches; visibility directives keep their controls, media, and browser state
alive.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use &lt;code>ng-switch&lt;/code> when one state selects one subtree:&lt;/p>
&lt;!-- tested-by: src/directive/if/if.spec.ts, src/directive/include/include.spec.ts, src/directive/switch/switch.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">ng-switch&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;checkout.step&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">cart-review&lt;/span> &lt;span style="color:#c4a000">ng-switch-when&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;review&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">cart-review&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">payment-form&lt;/span> &lt;span style="color:#c4a000">ng-switch-when&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;payment&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">payment-form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">order-confirmation&lt;/span> &lt;span style="color:#c4a000">ng-switch-when&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;complete&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">order-confirmation&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-switch-default&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Loading checkout...&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Change the state normally:&lt;/p></description></item><item><title>Swap server-rendered HTML into the page</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/swap-server-html/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/swap-server-html/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>An action needs fresh HTML from the server, but it does not justify a client
route or a JSON API followed by client-side rendering.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The endpoint must return a fragment rather than a complete document. Choose a
stable target that belongs to the same application and define what remains when
the request fails.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Let the server return the final HTML. Select the target with &lt;code>data-target&lt;/code> and
choose how to place the response with &lt;code>swap&lt;/code>:&lt;/p></description></item><item><title>Run an effect when state changes</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/effects/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/effects/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A state change must update something outside AngularTS, such as analytics,
storage, a chart, or another browser library.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use an effect only for work outside AngularTS rendering. Identify the scope that
owns the external resource and the operation that releases it.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Register a &lt;code>watch&lt;/code> for the scope expression that drives the external work:&lt;/p>
&lt;!-- tested-by: src/core/scope/scope.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">stopThemeEffect&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">scope&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">watch&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;settings.theme&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">theme&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">themeStore&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">save&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">theme&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">chart&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">setTheme&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">theme&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A watch listener runs after the write, in a microtask. Several synchronous
writes to the same property are coalesced before listeners run:&lt;/p></description></item><item><title>Handle DOM and scope events</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/event-handling/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/event-handling/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The page must react to user input, control browser event behavior, or notify
related scopes.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Start from a native user interaction and decide whether communication is local
DOM behavior, a short scope notification, or durable shared state.&lt;/p>
&lt;h2 id="handle-a-dom-event">Handle a DOM event&lt;a class="td-heading-self-link" href="#handle-a-dom-event" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use the directive named after the native event:&lt;/p>
&lt;!-- tested-by: src/directive/events/click.spec.ts, src/directive/events/event.spec.ts, src/core/scope/scope.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;cart.add(product)&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Add to cart&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-keydown&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;$event.key === &amp;#39;Escape&amp;#39; &amp;amp;&amp;amp; dialog.close()&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">aria-label&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;Search&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>$event&lt;/code> is the native event. Declare event policy on the same element:&lt;/p></description></item><item><title>Build and validate a form</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/forms/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/forms/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A form needs reactive values, validation messages, submit state, and a server
request without replacing native form behavior unnecessarily.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server endpoint must validate independently and return a deliberate success
or error format. Give every submitted native control a name.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Name the form and every control. Bind values with &lt;code>ng-model&lt;/code> and use native
validation attributes:&lt;/p>
&lt;!-- tested-by: src/directive/form/form.spec.ts, src/directive/model/model.spec.ts, src/directive/input/input.spec.ts, src/directive/http/post.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;signupForm&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/signup&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;account = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submitError = $res.message&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">loading&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">loading-class&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;is-saving&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span> &lt;span style="color:#c4a000">for&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Email&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;user.email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">ng-messages&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;signupForm.email.error&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-show&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;signupForm.email.dirty&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-message&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;required&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Enter your email.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-message&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Enter a valid email.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submitError&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-bind&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submitError&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-disabled&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;signupForm.invalid&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Create account&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The form name exposes its controller on scope. Each named &lt;code>ng-model&lt;/code> control has
an &lt;a href="../../../typedoc/classes/NgModelController.html">&lt;code>NgModelController&lt;/code>&lt;/a>.&lt;/p></description></item><item><title>Read and write REST resources</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/rest/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/rest/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Several screens call the same endpoint and repeat URL construction, response
mapping, and CRUD request code.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Register &lt;code>$rest&lt;/code> and &lt;code>$http&lt;/code> in the application that owns the data. Define
stable resource IDs and the server methods supported by the endpoint.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Create one typed resource with &lt;code>$rest&lt;/code>:&lt;/p>
&lt;!-- tested-by: src/services/rest/rest.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ts" data-lang="ts">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">interface&lt;/span> &lt;span style="color:#000">Task&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">id&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">number&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">title&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">string&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">complete&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">class&lt;/span> &lt;span style="color:#000">TaskRepository&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">static&lt;/span> &lt;span style="color:#000">$inject&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;$rest&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">];&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">private&lt;/span> &lt;span style="color:#000">tasks&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">ng.RestService&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Task&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#c4a000">number&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">constructor&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">$rest&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">ng.RestFactory&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">tasks&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">$rest&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Task&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#c4a000">number&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;/api/tasks&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">list() {&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">tasks&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">list&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">get&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">id&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">number&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">tasks&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">get&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">id&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;a href="../../../typedoc/classes/RestService.html">&lt;code>RestService&lt;/code>&lt;/a> provides &lt;code>list()&lt;/code>,
&lt;code>get()&lt;/code>, &lt;code>create()&lt;/code>, &lt;code>update()&lt;/code>, and &lt;code>delete()&lt;/code>. Writes stay close to HTTP:&lt;/p></description></item><item><title>Authenticate requests</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/authentication/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/authentication/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Requests need authentication, but controllers should not copy tokens or
credential flags into every call.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server must authenticate and authorize every request. Choose cookie or
bearer transport, define session expiry, and register any router states used
after login.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Prefer a server-managed, HttpOnly cookie when the application and API can share
a cookie session:&lt;/p>
&lt;!-- tested-by: src/router/transition/security-policy.spec.ts, src/services/http/http.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">session&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span> &lt;span style="color:#000">currentUser&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#204a87;font-weight:bold">null&lt;/span> &lt;span style="color:#000;font-weight:bold">};&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">angular&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">createModule&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;app&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">[])&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">value&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;session&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">session&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">config&lt;/span>&lt;span style="color:#000;font-weight:bold">({&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">$security&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">fallback&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;deny&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">isAuthenticated&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">()&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000">session&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">currentUser&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">!==&lt;/span> &lt;span style="color:#204a87;font-weight:bold">null&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">credentials&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span> &lt;span style="color:#000">cookie&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#204a87;font-weight:bold">true&lt;/span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">})&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;LoginController&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#39;session&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">function&lt;/span> &lt;span style="color:#000">LoginController&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">session&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">credentials&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000;font-weight:bold">{};&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">signedIn&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">user&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">session&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">currentUser&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">user&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">};&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">]);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>$http&lt;/code> and &lt;code>$rest&lt;/code> consult &lt;code>$security&lt;/code> before a request and enable browser
credentials when policy allows it. Login remains a normal server request:&lt;/p></description></item><item><title>Cache REST reads</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/caching/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/caching/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Reference data is requested repeatedly even though it changes infrequently.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Provide a &lt;a href="../../../typedoc/interfaces/RestCacheStore.html">&lt;code>RestCacheStore&lt;/code>&lt;/a>
implementation and classify the response as public, user-specific, mutable, or
immutable before selecting a policy.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Start with a cache store. This in-memory version lasts until the page reloads:&lt;/p>
&lt;!-- tested-by: src/services/rest/rest.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">class&lt;/span> &lt;span style="color:#000">MemoryRestCache&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">entries&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">new&lt;/span> &lt;span style="color:#000">Map&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">async&lt;/span> &lt;span style="color:#000">get&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">key&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">entries&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">get&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">key&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">async&lt;/span> &lt;span style="color:#000">set&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">key&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">value&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">entries&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">set&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">key&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">value&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">async&lt;/span> &lt;span style="color:#204a87;font-weight:bold">delete&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">key&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">entries&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">delete&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">key&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">async&lt;/span> &lt;span style="color:#000">deletePrefix&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">prefix&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">for&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">key&lt;/span> &lt;span style="color:#204a87;font-weight:bold">of&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">entries&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">keys&lt;/span>&lt;span style="color:#000;font-weight:bold">())&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">if&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">key&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">startsWith&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">prefix&lt;/span>&lt;span style="color:#000;font-weight:bold">))&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">entries&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">delete&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">key&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">appCache&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">new&lt;/span> &lt;span style="color:#000">MemoryRestCache&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The object implements
&lt;a href="../../../typedoc/interfaces/RestCacheStore.html">&lt;code>RestCacheStore&lt;/code>&lt;/a>. Replace it
with IndexedDB or another persistent store when cached data must survive a page
reload. Then wrap the HTTP REST backend:&lt;/p></description></item><item><title>Add application routes</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/routing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/routing/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A client-owned area needs URLs, back-button support, nested views, and route
data. A normal server page is no longer enough for that area.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use client routing only inside an area the browser must own. The server must
still serve the initial application URL and authentication endpoints.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Register states on the module:&lt;/p>
&lt;!-- tested-by: src/router/directives/state-directives.spec.ts, src/router/directives/view-directive.spec.ts, src/router/router.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ts" data-lang="ts">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">accountRoutes&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;account&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">url&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;/account&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">component&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;accountHome&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;account.orders&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">url&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;/orders&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">component&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;orderList&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">policy&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">navigation&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span> &lt;span style="color:#000">authenticated&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">redirectTo&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;login&amp;#39;&lt;/span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;account.order&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">url&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;/orders/:id&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">component&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;orderDetail&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">policy&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">navigation&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span> &lt;span style="color:#000">authenticated&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">redirectTo&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;login&amp;#39;&lt;/span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">]&lt;/span> &lt;span style="color:#204a87;font-weight:bold">as&lt;/span> &lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">satisfies&lt;/span> &lt;span style="color:#204a87;font-weight:bold">readonly&lt;/span> &lt;span style="color:#000">ng&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">RouterModuleDeclaration&lt;/span>&lt;span style="color:#000;font-weight:bold">[];&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">angular&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">createModule&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;account&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">[]).&lt;/span>&lt;span style="color:#000">router&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">accountRoutes&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Render the active state and create links:&lt;/p></description></item><item><title>Load content when it enters the viewport</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-viewport/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-viewport/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A chart, comment list, or request should not start until the user scrolls near
it.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Measure the initial request or CPU work first. The deferred feature must have a
visible loading or empty state when it has not started.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use &lt;code>ng-viewport&lt;/code> and run the enter expression once:&lt;/p>
&lt;!-- tested-by: src/directive/viewport/viewport.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-viewport&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-viewport-once&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-viewport-margin&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;200px 0px&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-enter&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;comments.load()&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;comments.loading&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Loading comments...&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">comment-list&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;comments.ready&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">comment-list&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The margin starts work 200 pixels before the section enters the viewport.
&lt;code>data-viewport-once&lt;/code> stops later enter events after the first one.&lt;/p></description></item><item><title>Receive live server events</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-sse/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-sse/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server must push notifications or status updates to the page without client
polling.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server must support &lt;code>text/event-stream&lt;/code>, flush events, and handle
reconnects. Decide what the page shows before the first event arrives.&lt;/p>
&lt;p>The browser side uses &lt;a href="../../../typedoc/types/SseService.html">&lt;code>SseService&lt;/code>&lt;/a>
through &lt;code>ng-sse&lt;/code>. AngularTS owns the
&lt;a href="../../../typedoc/interfaces/SseConnection.html">&lt;code>SseConnection&lt;/code>&lt;/a>, reconnects
it, and closes it when the scope is destroyed.&lt;/p>
&lt;p>For a custom production runtime, include &lt;code>sseModule&lt;/code> from
&lt;code>@angular-wave/angular.ts/runtime/realtime&lt;/code>. Do not include the aggregate
&lt;code>realtimeModule&lt;/code> unless the same runtime also uses WebSocket and WebTransport.&lt;/p></description></item><item><title>Move CPU-heavy work off the main thread</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-worker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-worker/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Sorting, compression, or data processing blocks input and rendering on the main
browser thread.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Profile a realistic input and define a serializable message contract. Browser
APIs and DOM nodes cannot be passed to the worker as ordinary values.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Point &lt;code>ng-worker&lt;/code> at a worker file and bind its result:&lt;/p>
&lt;!-- tested-by: src/directive/worker/worker.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-worker&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/workers/sort.js&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-params&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{ items: products }&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-result&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;sortedProducts = $result&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;sortError = error&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">trigger&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;click&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Sort products
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span> &lt;span style="color:#c4a000">ng-repeat&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;product in sortedProducts&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ product.name }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The worker receives &lt;code>data-params&lt;/code> through &lt;code>postMessage&lt;/code>:&lt;/p></description></item><item><title>Load a WebAssembly module</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-wasm/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-wasm/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A calculation already exists as WebAssembly and the page needs to call its
exports without writing module-loading lifecycle code.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Have a deployed WebAssembly module and know its exported function contract. The
server must send the correct MIME type.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Load the module with &lt;code>ng-wasm&lt;/code> and name its scope resource with &lt;code>as&lt;/code>:&lt;/p>
&lt;!-- tested-by: src/directive/wasm/wasm.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">ng-wasm&lt;/span> &lt;span style="color:#c4a000">src&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/wasm/shipping.wasm&amp;#34;&lt;/span> &lt;span style="color:#c4a000">as&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;shipping&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;shipping.status === &amp;#39;loading&amp;#39;&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Loading shipping calculator...&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;shipping.status === &amp;#39;error&amp;#39;&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Shipping estimate is unavailable.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;shipping.status === &amp;#39;ready&amp;#39;&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Shipping: {{ shipping.exports.quote(cart.weightGrams, destination.zone) }}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cents
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>AngularTS exposes a
&lt;a href="../../../typedoc/interfaces/WasmResource.html">&lt;code>WasmResource&lt;/code>&lt;/a> as &lt;code>shipping&lt;/code>.
Check &lt;code>status&lt;/code> before calling the pricing export. The cart and destination stay
in normal reactive scope state.&lt;/p></description></item><item><title>Edit a server record in place</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/inline-edit/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/inline-edit/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A user should edit one record without leaving the page. The server owns
validation and returns the saved record.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The page already has the record ID and summary. The endpoint accepts JSON and
returns field errors with status &lt;code>422&lt;/code>.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;profile = {&amp;#34;id&amp;#34;:42,&amp;#34;name&amp;#34;:&amp;#34;Ada&amp;#34;}; editing = false; errors = {}&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;!editing&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ profile.name }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;!editing&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;editing = true&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Edit name&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;editing&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-put&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/profiles/{{ profile.id }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;profile = $res; editing = false; errors = {}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;name&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;profile.name&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.name&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ errors.name }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Save&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;editing = false&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Cancel&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>PUT /api/profiles/42
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Content-Type: application/json
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{&amp;#34;name&amp;#34;:&amp;#34;Ada Lovelace&amp;#34;}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>HTTP/1.1 422 Unprocessable Content
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Content-Type: application/json
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{&amp;#34;name&amp;#34;:&amp;#34;That name is already used&amp;#34;}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="what-angularts-wires">What AngularTS wires&lt;a class="td-heading-self-link" href="#what-angularts-wires" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The form creates JSON from named controls. A &lt;code>2xx&lt;/code> response replaces &lt;code>profile&lt;/code>;
a &lt;code>4xx&lt;/code> response becomes &lt;code>$res&lt;/code> and stays beside the editor.&lt;/p></description></item><item><title>Delete a row without rebuilding its list</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/delete-row/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/delete-row/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Deleting one item should not recreate the list, lose scroll position, or remove
the row before the server authorizes the action.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server must authorize deletion and return success only after the record is
gone. Give the rendered row a stable DOM ID that is unique on the page.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;task-42&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Send invoice&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-delete&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/tasks/42&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#task-42&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;delete&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;deleteError = $res.message&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Delete
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;deleteError&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ deleteError }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Return &lt;code>204 No Content&lt;/code> only after authorization and deletion succeed. Return a
&lt;code>403&lt;/code> or &lt;code>409&lt;/code> JSON body such as &lt;code>{&amp;quot;message&amp;quot;:&amp;quot;This task is locked&amp;quot;}&lt;/code> when the
row must remain.&lt;/p></description></item><item><title>Search while the user types</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/active-search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/active-search/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Search should feel immediate without sending a request for every keystroke or
letting an older response replace newer results.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The search endpoint must accept a bounded query and echo its normalized query in
the JSON response. Decide the minimum useful query length and result limit.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;query = &amp;#39;&amp;#39;; results = []&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;search&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;query&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;query&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/search?q={{ query }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-trigger&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;input&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-delay&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;250&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;$res.query === query &amp;amp;&amp;amp; (results = $res.items)&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;query &amp;amp;&amp;amp; !results.length&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>No results for {{ query }}.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span> &lt;span style="color:#c4a000">ng-repeat&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;result in results&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ result.name }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Echo the normalized query with the results: &lt;code>{&amp;quot;query&amp;quot;:&amp;quot;boots&amp;quot;,&amp;quot;items&amp;quot;:[...] }&lt;/code>.
The equality check prevents a slow response for an earlier query from winning.&lt;/p></description></item><item><title>Load one select from another</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/dependent-selects/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/dependent-selects/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A city, model, or category list depends on an earlier selection and should not
be loaded before it is needed.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The parent values must use stable server identifiers. The child endpoint must
validate the parent identifier and return only choices valid for it.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;countries = [{code:&amp;#39;LV&amp;#39;, name:&amp;#39;Latvia&amp;#39;}, {code:&amp;#39;EE&amp;#39;, name:&amp;#39;Estonia&amp;#39;}]; cities = []&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;country&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;country&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-options&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;item.code as item.name for item in countries&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/cities?country={{ country }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;cities = $res; city = undefined&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;city&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;city&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-options&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;item.id as item.name for item in cities&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-disabled&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;!cities.length&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>&lt;code>GET /api/cities?country=LV&lt;/code> returns a bounded JSON array such as
&lt;code>[{&amp;quot;id&amp;quot;:1,&amp;quot;name&amp;quot;:&amp;quot;Riga&amp;quot;}]&lt;/code>. Reject unknown country codes on the server.&lt;/p></description></item><item><title>Load the next page near the viewport</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/infinite-scroll/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/infinite-scroll/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A long feed should load another server-rendered page shortly before the user
reaches the end without rebuilding existing rows.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server must expose normal paginated URLs and return HTML fragments with
stable row identity. Keep explicit pagination as the non-JavaScript and keyboard
fallback.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Order 1001&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Order 1002&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;next-orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-viewport&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-viewport-once&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-viewport-margin&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;300px 0px&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-enter&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;nextPage = 2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/orders?page={{ nextPage }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-latch&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{{ nextPage }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#next-orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;outerHTML&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Loading more orders...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Return new &lt;code>&amp;lt;li&amp;gt;&lt;/code> rows followed by the same marker configured for page 3. Omit
the marker on the last page. Keep a normal paginated URL so refresh and sharing
work.&lt;/p></description></item><item><title>Update immediately and roll back on failure</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/optimistic-update/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/optimistic-update/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A reversible action such as completing a task should feel immediate, but a
rejected request must restore the last confirmed value.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose a reversible, low-risk action and retain the last confirmed server value.
The endpoint must return the canonical value or a clear conflict response.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;task = {&amp;#34;id&amp;#34;:42,&amp;#34;complete&amp;#34;:false}; confirmed = false&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-put&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/tasks/{{ task.id }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;task = $res; confirmed = $res.complete; saveError = undefined&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;task.complete = confirmed; saveError = $res.message&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;complete&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;checkbox&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;task.complete&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Complete
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Save&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;saveError&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ saveError }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Return the canonical task after success. Return &lt;code>409 Conflict&lt;/code> with
&lt;code>{&amp;quot;message&amp;quot;:&amp;quot;Task changed on another device&amp;quot;}&lt;/code> when the submitted version is
stale.&lt;/p></description></item><item><title>Return users to login after a session expires</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/session-expiration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/session-expiration/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A user opens a private action after their cookie session expires. The
application must show login rather than leaving a broken panel.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Register the login router state and configure the request credential transport.
Decide how the login flow stores and restores the intended destination.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/account&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;account = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;sessionError = $res.message&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-state-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;login&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Refresh account
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;sessionError&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ sessionError }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The private endpoint returns &lt;code>401&lt;/code> with &lt;code>{&amp;quot;message&amp;quot;:&amp;quot;Your session expired&amp;quot;}&lt;/code>.
The login state records the intended state and returns there after successful
login.&lt;/p></description></item><item><title>Cache reference data without sharing user data</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/cached-reference-data/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/cached-reference-data/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Country, currency, or category lists are downloaded repeatedly even though they
change rarely and are identical for every user.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Provide an application cache implementing the linked cache-store contract.
Confirm the endpoint is independent of user identity before sharing entries.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ts" data-lang="ts">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">import&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">CachedRestBackend&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">HttpRestBackend&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span> &lt;span style="color:#204a87;font-weight:bold">from&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;@angular-wave/angular.ts/services/rest&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">referenceBackend&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">new&lt;/span> &lt;span style="color:#000">CachedRestBackend&lt;/span>&lt;span style="color:#000;font-weight:bold">({&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">network&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">new&lt;/span> &lt;span style="color:#000">HttpRestBackend&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">$http&lt;/span>&lt;span style="color:#000;font-weight:bold">),&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">cache&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">appCache&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">policy&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">({&lt;/span> &lt;span style="color:#000">url&lt;/span> &lt;span style="color:#000;font-weight:bold">})&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">url&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">startsWith&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;/api/reference/&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">?&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;cache-first&amp;#39;&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;network-first&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">countries&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">$rest&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Country&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#c4a000">string&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;/api/reference/countries&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">Country&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">backend&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">referenceBackend&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Country
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;shipping.country&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-options&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;country.code as country.name for country in countries&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The cached result is ordinary application state. Bind it like any other list;
the template does not need to know which cache policy supplied it.&lt;/p></description></item><item><title>Cancel a file upload and handle server rejection</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/upload-cancel/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/upload-cancel/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A large upload needs cancellation and useful server errors. The current fetch
transport does not expose upload progress events.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Register the controller on the application module and attach it to the form. Set
server-side size, content, authorization, and storage limits before accepting
files.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">class&lt;/span> &lt;span style="color:#000">UploadController&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">static&lt;/span> &lt;span style="color:#000">$inject&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;$http&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">];&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">constructor&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">$http&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">$http&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">$http&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">async&lt;/span> &lt;span style="color:#000">send&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">file&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">cancellation&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87">Promise&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">withResolvers&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">body&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">new&lt;/span> &lt;span style="color:#000">FormData&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">body&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">append&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;file&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">file&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">try&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">await&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">$http&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">post&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;/api/uploads&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">body&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">timeout&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">cancellation&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">promise&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span> &lt;span style="color:#204a87;font-weight:bold">catch&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">error&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">if&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">error&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">xhrStatus&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">!==&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;abort&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">error&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">error&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">data&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">message&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">cancel&lt;/span>&lt;span style="color:#000;font-weight:bold">()&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">cancellation&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">?&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">resolve&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-controller&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;UploadController as upload&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-submit&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;upload.send(upload.files[0])&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;file&amp;#34;&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;file&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;upload.files&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Upload&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;upload.cancel()&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Cancel&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;upload.error&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ upload.error }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Validate size, MIME signature, filename, authorization, and storage limits on
the server. Return &lt;code>413&lt;/code> for size limits and &lt;code>422&lt;/code> JSON for rejected content.&lt;/p></description></item><item><title>Load a dialog from the server</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/server-dialog/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/server-dialog/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A confirmation dialog needs current server data, but its trigger must keep focus
and remain usable if loading fails.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The trigger must remain in the DOM while the fragment is open. The server
fragment owns its accessible title, initial focus, close behavior, and
authorization result.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-el&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;dialogTrigger&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/delete-dialog&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#dialog-host&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;innerHTML&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;dialogError = $res.message&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Delete account
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;dialog-host&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;dialogError&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ dialogError }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Return a labelled dialog fragment with a focused cancel button. Its close action
calls &lt;code>dialogTrigger.focus()&lt;/code> before removing the fragment. Return &lt;code>403&lt;/code> JSON
when the current user may no longer perform the action.&lt;/p></description></item><item><title>Understand the similarity to HTMX</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/htmx-patterns/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/htmx-patterns/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>AngularTS HTTP directives look familiar if you know HTMX. You want to understand
the shared approach without assuming the APIs behave alike.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Start with the AngularTS HTTP directive reference. Treat HTMX knowledge as
background for the server-first design, not as documentation for AngularTS.&lt;/p>
&lt;h2 id="similar-design-questions">Similar design questions&lt;a class="td-heading-self-link" href="#similar-design-questions" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Design question&lt;/th>
 &lt;th>AngularTS mechanism&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Trigger a request&lt;/td>
 &lt;td>&lt;code>ng-get&lt;/code>, &lt;code>ng-post&lt;/code>, &lt;code>ng-put&lt;/code>, &lt;code>ng-delete&lt;/code>, &lt;code>data-trigger&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Choose the destination&lt;/td>
 &lt;td>&lt;code>data-target&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Choose insertion behavior&lt;/td>
 &lt;td>&lt;code>swap&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Render a server fragment&lt;/td>
 &lt;td>Return HTML; AngularTS inserts and compiles it&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Read JSON&lt;/td>
 &lt;td>Assign &lt;code>$res&lt;/code> in &lt;code>on-success&lt;/code> or &lt;code>on-error&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Show request state&lt;/td>
 &lt;td>&lt;code>loading&lt;/code>, &lt;code>loading-class&lt;/code>, bindings&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Navigate after success&lt;/td>
 &lt;td>&lt;code>data-state-success&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Prefetch from intent&lt;/td>
 &lt;td>Event trigger plus hidden scope state&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Lazy load near the viewport&lt;/td>
 &lt;td>&lt;code>ng-viewport&lt;/code> plus an HTTP directive&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Keep local interaction state&lt;/td>
 &lt;td>Scope, controller, or typed component view&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="where-the-approach-feels-similar">Where the approach feels similar&lt;a class="td-heading-self-link" href="#where-the-approach-feels-similar" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Both approaches encourage useful questions for click-to-edit, active search,
polling, lazy loading, server validation, fragment swaps, pagination, and
prefetching: who renders the result, what triggers the request, where it goes,
and what failure looks like.&lt;/p></description></item><item><title>Design an HTTP response for the UI</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/http-response-contracts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/http-response-contracts/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A directive can only handle success, validation, navigation, and swaps correctly
when the server response has a deliberate contract.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose whether the server or browser renders the result. Write down what the user
should see after success, invalid input, expired authentication, conflict, and
unexpected failure.&lt;/p>
&lt;h2 id="choose-the-response">Choose the response&lt;a class="td-heading-self-link" href="#choose-the-response" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Situation&lt;/th>
 &lt;th>Response contract&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Saved data is needed locally&lt;/td>
 &lt;td>&lt;code>2xx application/json&lt;/code> with the canonical saved record&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Only success matters&lt;/td>
 &lt;td>&lt;code>204 No Content&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Server owns the replacement UI&lt;/td>
 &lt;td>&lt;code>2xx text/html&lt;/code> with one fragment&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>User can correct submitted values&lt;/td>
 &lt;td>&lt;code>422 application/json&lt;/code> keyed by field name&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Authentication expired&lt;/td>
 &lt;td>&lt;code>401 application/json&lt;/code> with a safe user message&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>User lacks permission&lt;/td>
 &lt;td>&lt;code>403 application/json&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Submitted version is stale&lt;/td>
 &lt;td>&lt;code>409 application/json&lt;/code> with conflict details&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Server failed unexpectedly&lt;/td>
 &lt;td>&lt;code>5xx application/json&lt;/code> with a public message ID&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Use &lt;code>on-success&lt;/code> or &lt;code>on-error&lt;/code> for JSON. Use &lt;code>data-target&lt;/code> and &lt;code>swap&lt;/code> for HTML.
Do not return HTML error pages to a JSON interaction or &lt;code>200&lt;/code> for rejected form
data merely to avoid the error path.&lt;/p></description></item><item><title>Make a server-driven interaction accessible</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/accessible-requests/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/accessible-requests/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A request updates the page visually, but keyboard and screen-reader users also
need an operable trigger, announced status, and predictable focus.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use a native button or link for the trigger. Choose a stable result container and
decide whether focus should remain on the trigger or move to the new result.&lt;/p>
&lt;h2 id="working-example">Working example&lt;a class="td-heading-self-link" href="#working-example" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/get.spec.ts, src/directive/el/el.spec.ts, src/directive/aria/aria.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;requestStatus = &amp;#39;Results not loaded&amp;#39;&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#order-results&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;innerHTML&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">loading&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;requestStatus = &amp;#39;Orders loaded&amp;#39;; orderResults.focus()&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;requestStatus = $res.message&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">aria-describedby&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;order-status&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Load orders
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;order-status&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;status&amp;#34;&lt;/span> &lt;span style="color:#c4a000">aria-live&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;polite&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {{ requestStatus }}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;order-results&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-el&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orderResults&amp;#34;&lt;/span> &lt;span style="color:#c4a000">tabindex&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;-1&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Return a heading and order rows as one HTML fragment. Return JSON with a short,
actionable &lt;code>message&lt;/code> for errors so the live region can announce it.&lt;/p></description></item><item><title>Audit a server-driven interaction before shipping</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/secure-request/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/secure-request/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A form or HTTP directive works, but its security depends on decisions spread
between markup, request configuration, the endpoint, and storage.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose one real state-changing request. Record its authenticated user, resource,
method, credential transport, response type, cache path, and uploaded content.&lt;/p>
&lt;h2 id="audit-the-interaction">Audit the interaction&lt;a class="td-heading-self-link" href="#audit-the-interaction" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Surface&lt;/th>
 &lt;th>Shipping check&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Authorization&lt;/td>
 &lt;td>Server verifies this user may act on this resource&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cookie request&lt;/td>
 &lt;td>Server validates CSRF protection on every state-changing method&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Bearer credential&lt;/td>
 &lt;td>Token never appears in URL, HTML, storage logs, or error output&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>HTML response&lt;/td>
 &lt;td>Server escapes untrusted values before AngularTS compiles it&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>JSON error&lt;/td>
 &lt;td>Body contains safe field messages, not stack or database details&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cache&lt;/td>
 &lt;td>Private entries are partitioned and cleared on logout&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Upload&lt;/td>
 &lt;td>Server checks size, MIME signature, filename, and storage limits&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Redirect&lt;/td>
 &lt;td>Destination is allowlisted rather than copied from user input&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Client validation, hidden buttons, route policy, and disabled controls improve
the user experience. None of them authorize a server operation.&lt;/p></description></item><item><title>Keep a form useful before AngularTS starts</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/progressive-enhancement/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/progressive-enhancement/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A request should still work when JavaScript is slow, unavailable, or fails to
start.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Make the endpoint accept a normal form submission and return a complete page.
Only then add AngularTS behavior to improve the interaction.&lt;/p>
&lt;h2 id="start-with-the-browsers-form-behavior">Start with the browser&amp;rsquo;s form behavior&lt;a class="td-heading-self-link" href="#start-with-the-browsers-form-behavior" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/post.spec.ts, src/router/view/view.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">action&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">method&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;post&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-state-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Quantity
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;quantity&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;number&amp;#34;&lt;/span> &lt;span style="color:#c4a000">min&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;1&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Place order&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.quantity&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ errors.quantity }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Without AngularTS, the browser posts the form to &lt;code>/orders&lt;/code>. With AngularTS, the
HTTP directive submits it without a page reload and the router enters &lt;code>orders&lt;/code>
after success. The endpoint must accept both the browser&amp;rsquo;s form encoding and the
enhanced request body.&lt;/p></description></item><item><title>Debug an HTTP interaction from the browser</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/debug-http-interaction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/debug-http-interaction/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A click or submission produces the wrong result and you need to find whether the
problem is the element, scope, request, response, or rendering.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Open the Elements, Console, and Network panels. Select the element that owns the
HTTP directive so it is available as &lt;code>$0&lt;/code> in the console.&lt;/p>
&lt;h2 id="follow-one-interaction">Follow one interaction&lt;a class="td-heading-self-link" href="#follow-one-interaction" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/angular.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">scope&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">angular&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">getScope&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">$0&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">scope&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">order&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Check the directive attributes on &lt;code>$0&lt;/code>, inspect the values used by its
expressions, then perform the interaction with Network recording enabled. Read
the request method, URL, payload, status, content type, and response before
looking at the rendered result.&lt;/p></description></item><item><title>Control repeated requests</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/control-repeat-requests/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/control-repeat-requests/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Typing, scrolling, hovering, or repeated clicks can start more requests than the
user needs.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Record the interaction in the Network panel. Count requests, transferred bytes,
server time, and stale responses. Do not add request control without seeing the
problem first.&lt;/p>
&lt;h2 id="choose-the-smallest-control">Choose the smallest control&lt;a class="td-heading-self-link" href="#choose-the-smallest-control" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>What you observe&lt;/th>
 &lt;th>First response&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Fast typing starts a request per key&lt;/td>
 &lt;td>Add a short delay after input settles&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Scroll or resize fires continuously&lt;/td>
 &lt;td>Throttle the event&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>The same read repeats unchanged&lt;/td>
 &lt;td>Reuse an appropriate public or user-partitioned cache&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>An old search overwrites a newer one&lt;/td>
 &lt;td>Reject stale results or cancel the old request&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Hover prefetch repeats&lt;/td>
 &lt;td>Guard it with loaded and loading state&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Double-click repeats a write&lt;/td>
 &lt;td>Disable while pending and make the server idempotent&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Use a promise-valued &lt;code>$http&lt;/code> &lt;code>timeout&lt;/code> to cancel an obsolete programmatic
request. Treat &lt;code>xhrStatus === &amp;quot;abort&amp;quot;&lt;/code> as cancellation rather than a server
failure. HTTP directive flows should usually prevent another trigger while the
current request is pending instead of creating custom cancellation code.&lt;/p></description></item><item><title>Show validation errors returned by the server</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/server-validation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/server-validation/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A form needs immediate, useful errors without duplicating the server&amp;rsquo;s validation
rules in browser code.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Make the endpoint return &lt;code>422&lt;/code> with a JSON object whose keys match form control
names. Use short messages that are safe to show directly to the user.&lt;/p>
&lt;h2 id="render-the-error-object">Render the error object&lt;a class="td-heading-self-link" href="#render-the-error-object" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/post.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/profile&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;profile = $res; errors = {}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span> &lt;span style="color:#c4a000">ng-class&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{ error: errors.email }&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Email
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{{ profile.email }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">aria-invalid&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{{ errors.email !== undefined }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-keyup&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.email = undefined&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.email&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ errors.email }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Save profile&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The same error object drives the message, error class, and accessibility state.
Browser validation can improve feedback, but the server still checks every value.&lt;/p></description></item><item><title>Protect a cookie-authenticated form from CSRF</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/csrf-protected-form/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/csrf-protected-form/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A form uses authentication cookies, so another site may be able to cause the
browser to send an unwanted state-changing request.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Configure CSRF protection on the server. Generate a token tied to the user or
session and render it into the page. Cookie &lt;code>SameSite&lt;/code> settings help, but they do
not replace server-side CSRF validation.&lt;/p>
&lt;h2 id="submit-the-server-issued-token">Submit the server-issued token&lt;a class="td-heading-self-link" href="#submit-the-server-issued-token" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/post.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;hidden&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;csrf_token&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;SERVER_RENDERED_TOKEN&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> New email
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Change email&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Replace &lt;code>SERVER_RENDERED_TOKEN&lt;/code> in the server template. AngularTS serializes the
named hidden control with the rest of the form; the server validates it before
changing state.&lt;/p></description></item><item><title>Confirm a destructive action in place</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/confirm-delete/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/confirm-delete/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A single accidental click can delete important data.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Make deletion authorization and resource ownership checks authoritative on the
server. Decide whether the operation is reversible and say so in the interface.&lt;/p>
&lt;h2 id="ask-for-a-second-explicit-action">Ask for a second explicit action&lt;a class="td-heading-self-link" href="#ask-for-a-second-explicit-action" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/delete.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;confirming = false; deleted = false&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;!deleted&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h2&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Quarterly report&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h2&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;confirming = true&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Delete&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;confirming&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;alert&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>This permanently deletes the report.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-delete&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/reports/42&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;deleted = true&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;deleteError = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Delete permanently
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;confirming = false&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Cancel&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;deleteError&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ deleteError.message }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The first button changes only local state. The second button sends the request
and names the exact consequence.&lt;/p></description></item><item><title>Handle two people editing the same record</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/edit-conflict/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/edit-conflict/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>One person can overwrite a change saved by someone else while both are editing
the same record.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Give each record a version, revision, or strong ETag. Require the client to send
the version it originally loaded with every update.&lt;/p>
&lt;h2 id="send-the-version-with-the-edit">Send the version with the edit&lt;a class="td-heading-self-link" href="#send-the-version-with-the-edit" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/put.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-put&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/articles/42&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;article = $res; conflict = undefined&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;conflict = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;version&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;hidden&amp;#34;&lt;/span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{{ article.version }}&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Title
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;title&amp;#34;&lt;/span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{{ article.title }}&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Save article&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">aside&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;conflict.current&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Someone saved a newer version: {{ conflict.current.title }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;article = conflict.current; conflict = undefined&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Load newer version
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">aside&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Update only when the submitted version matches the stored version. Otherwise
return &lt;code>409&lt;/code> with a safe representation of the current record. Increment the
version atomically with the successful update.&lt;/p></description></item><item><title>Let the user retry a failed read</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/retry-failed-read/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/retry-failed-read/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A temporary network or server failure leaves a section empty or forces a full
page reload.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Keep reads safe and idempotent. Decide whether old data is more useful than an
empty screen while a refresh fails.&lt;/p>
&lt;h2 id="keep-recovery-next-to-the-result">Keep recovery next to the result&lt;a class="td-heading-self-link" href="#keep-recovery-next-to-the-result" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/get.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders = []; loadError = undefined&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders = $res; loadError = undefined&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;loadError = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Refresh orders
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;loadError&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;alert&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Orders could not be refreshed. Try again.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;!loadError &amp;amp;&amp;amp; orders.length === 0&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>No orders yet.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span> &lt;span style="color:#c4a000">ng-repeat&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;order in orders&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ order.number }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The existing list remains visible if refresh fails. The user controls when
another request is sent.&lt;/p></description></item><item><title>Paginate a large result on the server</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/server-pagination/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/server-pagination/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A large collection is slow to query, transfer, render, and navigate.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Make the server return a bounded page and stable next and previous URLs. Prefer a
cursor when records change frequently; use page numbers when random access is
important and the data is stable enough.&lt;/p>
&lt;h2 id="keep-real-navigation-urls">Keep real navigation URLs&lt;a class="td-heading-self-link" href="#keep-real-navigation-urls" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/get.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Orders 21–40&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">nav&lt;/span> &lt;span style="color:#c4a000">aria-label&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;Order pages&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">href&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/orders?page=1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/orders?page=1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;innerHTML&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Previous
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">href&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/orders?page=3&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/orders?page=3&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;innerHTML&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Next
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">nav&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>href&lt;/code> remains useful for opening a page in another tab and for normal
navigation before AngularTS starts. The HTTP directive can replace only the list
when the enhanced interaction runs.&lt;/p></description></item><item><title>Download a generated file with the browser</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/download-file/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/download-file/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A report or export needs to download without turning a large binary response into
scope state or manually constructing a browser blob.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Make the server stream the file with the correct &lt;code>Content-Type&lt;/code> and a safe
&lt;code>Content-Disposition&lt;/code> filename. Authorize the download on every request.&lt;/p>
&lt;h2 id="let-the-browser-own-the-response">Let the browser own the response&lt;a class="td-heading-self-link" href="#let-the-browser-own-the-response" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/core/compile/compile.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">action&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/reports/orders.csv&amp;#34;&lt;/span> &lt;span style="color:#c4a000">method&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;get&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> From
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;from&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;date&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> To
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;to&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;date&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Download CSV&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A native form lets the browser stream, name, save, and expose download progress
without retaining the file in AngularTS memory.&lt;/p></description></item><item><title>Replace a region with trusted server HTML</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/safe-html-fragment/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/safe-html-fragment/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server already renders a useful partial and returning JSON would duplicate
the same presentation rules in a client template.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose a stable target element. Treat every returned fragment as executable UI:
escape untrusted values on the server and allow only application-owned markup.&lt;/p>
&lt;h2 id="swap-the-fragment-into-a-named-region">Swap the fragment into a named region&lt;a class="td-heading-self-link" href="#swap-the-fragment-into-a-named-region" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/get.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/summary&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#account-summary&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;innerHTML&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Refresh summary
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;account-summary&amp;#34;&lt;/span> &lt;span style="color:#c4a000">aria-live&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;polite&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Summary not loaded.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>AngularTS wires directives and bindings in the returned application-owned
fragment. That makes server escaping and content ownership security requirements,
not optional cleanup.&lt;/p></description></item><item><title>Show a request ID when an operation fails</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/request-id/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/request-id/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A user reports “Save failed,” but operators cannot connect that report to one
server request among thousands.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Generate or accept a request ID at the trusted server edge, carry it through
logs and downstream calls, and return it in safe unexpected-error responses.&lt;/p>
&lt;h2 id="render-the-identifier-with-the-error">Render the identifier with the error&lt;a class="td-heading-self-link" href="#render-the-identifier-with-the-error" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/http/post.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/invoices&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;saveError = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Customer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;customer&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Create invoice&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;saveError&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;alert&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>The invoice could not be created.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;saveError.requestId&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Support code: {{ saveError.requestId }}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The user sees a stable support code, not internal diagnostics.&lt;/p></description></item><item><title>Check a server interaction before shipping</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/ship-interaction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/ship-interaction/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>An interaction works in the happy path but its production behavior has not been
checked as one complete system.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose one real user action and use its production-like endpoint and permissions.
Open the Elements, Console, and Network panels.&lt;/p>
&lt;h2 id="walk-the-whole-path">Walk the whole path&lt;a class="td-heading-self-link" href="#walk-the-whole-path" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Check these in order:&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Step&lt;/th>
 &lt;th>Question&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Page&lt;/td>
 &lt;td>Does the useful server-rendered page work before enhancement?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Input&lt;/td>
 &lt;td>Are labels, names, constraints, and server validation aligned?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Request&lt;/td>
 &lt;td>Is the method correct and sent only once?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Access&lt;/td>
 &lt;td>Does the server check authentication, authorization, and CSRF?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Response&lt;/td>
 &lt;td>Are status, content type, and body appropriate?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>State&lt;/td>
 &lt;td>Does success update only the intended scope and DOM?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Failure&lt;/td>
 &lt;td>Can the user understand, retry, cancel, or recover safely?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Concurrency&lt;/td>
 &lt;td>Can stale or duplicate requests corrupt state?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Accessibility&lt;/td>
 &lt;td>Are status and focus understandable without a pointer?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Operations&lt;/td>
 &lt;td>Can a request ID connect the visible failure to server logs?&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="failure-path">Failure path&lt;a class="td-heading-self-link" href="#failure-path" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Treat any unanswered row as unfinished implementation rather than documentation
debt. Fix the smallest owning layer: browser markup, AngularTS wiring, endpoint,
storage transaction, or operational logging.&lt;/p></description></item><item><title>Recover from a rate-limited request</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/rate-limit/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/rate-limit/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>An endpoint limits repeated requests, but the page reports a generic failure or
immediately retries and makes the limit worse.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Make the server return &lt;code>429&lt;/code> and a &lt;code>Retry-After&lt;/code> header. Use rate limits to
protect a resource, not as the only defense against abusive or unauthorized use.&lt;/p>
&lt;h2 id="keep-retry-under-the-users-control">Keep retry under the user&amp;rsquo;s control&lt;a class="td-heading-self-link" href="#keep-retry-under-the-users-control" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;limitError = undefined&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/reports/preview&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;preview = $res; limitError = undefined&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;limitError = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Refresh preview
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;limitError&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;alert&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {{ limitError.message }} Try again after {{ limitError.retryAfter }}.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;preview&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ preview.summary }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Do not run a tight automatic retry loop. Keep the last useful result visible and
tell the user when another attempt can succeed.&lt;/p></description></item><item><title>Run slow work as a background job</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/background-job/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/background-job/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A report, import, or media conversion takes too long for one request and becomes
fragile behind browser, proxy, or deployment timeouts.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Give the job a durable ID, owner, state, progress value, and expiry policy. Make
starting the same job twice safe when duplicate work would be expensive.&lt;/p>
&lt;h2 id="start-the-job-then-ask-for-status">Start the job, then ask for status&lt;a class="td-heading-self-link" href="#start-the-job-then-ask-for-status" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/exports&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;job = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Format
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;format&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">option&lt;/span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;csv&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>CSV&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">option&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Create export&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;job&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Status: {{ job.status }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/exports/current&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;job = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Refresh status
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;job.downloadUrl&amp;#34;&lt;/span> &lt;span style="color:#c4a000">href&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{{ job.downloadUrl }}&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Download&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Use manual refresh first. Add measured polling or server-sent events only when
the user benefits from continuous progress.&lt;/p></description></item><item><title>Make a critical write safe to repeat</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/idempotent-write/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/idempotent-write/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A double click, reconnect, proxy retry, or impatient refresh can submit the same
critical operation more than once.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Generate a unique operation key on the server-rendered page. Scope it to the
authenticated user and operation, and store the first result atomically.&lt;/p>
&lt;h2 id="submit-the-operation-key-with-the-form">Submit the operation key with the form&lt;a class="td-heading-self-link" href="#submit-the-operation-key-with-the-form" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/payments&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;paymentError = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;hidden&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;idempotency_key&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;SERVER_RENDERED_OPERATION_KEY&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Amount
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;amount&amp;#34;&lt;/span> &lt;span style="color:#c4a000">inputmode&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;decimal&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Pay once&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;paymentError&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;alert&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ paymentError.message }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Disabling the button improves feedback but cannot provide this guarantee. The
server key protects retries from every source.&lt;/p></description></item><item><title>Build a multi-step form on the server</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/multi-step-form/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/multi-step-form/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A long form needs several steps, but refreshing, navigating back, or changing
devices must not discard completed work.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Create a server-side draft with an owner and current step. Validate and save each
step independently. Make every step addressable with a normal URL.&lt;/p>
&lt;h2 id="enhance-a-normal-step-form">Enhance a normal step form&lt;a class="td-heading-self-link" href="#enhance-a-normal-step-form" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">action&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/checkout/address&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">method&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;post&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/checkout/address&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-state-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;checkout-payment&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Delivery address
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">textarea&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;address&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">textarea&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.address&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ errors.address }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Continue to payment&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The server saves the address before advancing. AngularTS can enter the next
router state after success, while the native action remains a working fallback.&lt;/p></description></item><item><title>Apply one action to several records</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/bulk-action/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/bulk-action/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Users need to update several records without opening and submitting each one
individually.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose a maximum batch size. Authorize every selected record independently and
decide whether the operation is atomic or may partially succeed.&lt;/p>
&lt;h2 id="submit-explicit-selected-controls">Submit explicit selected controls&lt;a class="td-heading-self-link" href="#submit-explicit-selected-controls" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/tasks/archive&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;result = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">fieldset&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">legend&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Tasks to archive&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">legend&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;task_42&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;checkbox&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span> Draft invoice&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;task_43&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;checkbox&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span> Review contract&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">fieldset&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Archive selected tasks&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;result&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Archived {{ result.archived }} tasks.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span> &lt;span style="color:#c4a000">ng-repeat&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;error in result.errors&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ error.message }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Named controls make the submitted selection inspectable in the Network panel.
For dynamic lists, use the server&amp;rsquo;s documented array representation consistently.&lt;/p></description></item><item><title>Archive first and offer restore</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/archive-restore/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/archive-restore/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Users need to remove an item from active work, but permanent deletion is too easy
to regret.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Model archived state on the server. Define retention, visibility, uniqueness,
restore permissions, and the separate conditions for permanent deletion.&lt;/p>
&lt;h2 id="keep-restore-beside-the-result">Keep restore beside the result&lt;a class="td-heading-self-link" href="#keep-restore-beside-the-result" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;archived = false&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;!archived&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/projects/42/archive&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;archived = true&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Archive project
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;archived&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;status&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Project archived.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/projects/42/restore&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;archived = false&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Restore
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The page changes only after each server operation succeeds.&lt;/p></description></item><item><title>Handle a permission rejection without hiding it</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/permission-denied/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/permission-denied/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The interface hides controls based on known permissions, but permissions can
change and direct or stale requests still reach the server.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Authorize every operation on the server using the authenticated user and current
resource. Client visibility is presentation, not enforcement.&lt;/p>
&lt;h2 id="render-the-server-rejection">Render the server rejection&lt;a class="td-heading-self-link" href="#render-the-server-rejection" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-put&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/team/42/settings&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;settings = $res; accessError = undefined&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;accessError = $res&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Team name
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;name&amp;#34;&lt;/span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{{ settings.name }}&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Save settings&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;accessError&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;alert&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {{ accessError.message }}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A disabled or hidden button can reduce confusion when permission is already
known, but the rejection path remains necessary.&lt;/p></description></item><item><title>Keep search and filters in the URL</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/url-filter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/url-filter/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Filters exist only in browser state, so refresh, sharing, Back, and opening a new
tab lose the current result.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Define stable query parameter names and defaults on the server. Return the same
result for the same authorized URL.&lt;/p>
&lt;h2 id="start-with-a-real-get-form">Start with a real GET form&lt;a class="td-heading-self-link" href="#start-with-a-real-get-form" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">action&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">method&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;get&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;innerHTML&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Status &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;status&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">option&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Open&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">option&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Search &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;q&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;search&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Apply filters&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders&amp;#34;&lt;/span> &lt;span style="color:#c4a000">aria-live&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;polite&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Choose filters to update the result.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The native GET form defines the canonical URL. Enhancement may replace the result
region, but it must preserve a URL that reproduces the same filters.&lt;/p></description></item><item><title>Log out with a state-changing form</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/logout/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/logout/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Logout is implemented as a GET link or only clears browser state, leaving the
server session active or allowing unwanted cross-site logout requests.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Provide a server &lt;code>POST&lt;/code> endpoint that invalidates the session and rotates relevant
credentials. Decide which private caches and client state must be discarded.&lt;/p>
&lt;h2 id="submit-logout-as-a-protected-form">Submit logout as a protected form&lt;a class="td-heading-self-link" href="#submit-logout-as-a-protected-form" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">action&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/logout&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">method&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;post&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/logout&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-state-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;signed-out&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;hidden&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;csrf_token&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;SERVER_RENDERED_TOKEN&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Log out&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The normal form works without client routing. The enhanced form can enter a
public signed-out state after the server confirms invalidation.&lt;/p></description></item><item><title>Keep requests same-origin unless they must cross origins</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/cross-origin-request/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/cross-origin-request/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The page and API use different origins, introducing preflight,
credential, cookie, caching, and deployment behavior that same-origin requests
avoid.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Ask whether the application server can proxy the API under the page&amp;rsquo;s origin.
Prefer that simpler setup unless direct browser access to the other origin is a
real requirement.&lt;/p>
&lt;h2 id="configure-the-server-not-the-browser-workaround">Configure the server, not the browser workaround&lt;a class="td-heading-self-link" href="#configure-the-server-not-the-browser-workaround" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Allow only known application origins, required methods, and required headers.
When cookies are involved, use explicit origins and credentials; wildcard origin
responses cannot safely represent authenticated access. Keep CSRF protection for
cookie-authenticated state changes.&lt;/p></description></item><item><title>Handle a uniqueness race on submit</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/unique-race/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/unique-race/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The page checks that a name is available, but another request claims it before
the user submits.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Enforce uniqueness with a database constraint. Availability checks improve
feedback but can never reserve the value unless the server explicitly does so.&lt;/p>
&lt;h2 id="return-the-conflict-to-the-field">Return the conflict to the field&lt;a class="td-heading-self-link" href="#return-the-conflict-to-the-field" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/teams&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span> &lt;span style="color:#c4a000">ng-class&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{ error: errors.slug }&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Team address
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;slug&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">required&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">aria-invalid&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{{ errors.slug !== undefined }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-keyup&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.slug = undefined&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.slug&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ errors.slug }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Create team&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Attempt the insert and translate the known uniqueness violation into &lt;code>409&lt;/code> or a
field-oriented &lt;code>422&lt;/code> body such as &lt;code>{&amp;quot;slug&amp;quot;:&amp;quot;That address is already used&amp;quot;}&lt;/code>.
Do not expose database error text.&lt;/p></description></item><item><title>Submit money without floating-point surprises</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/money-values/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/money-values/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>An amount changes by a cent because browser or server code treats currency as a
binary floating-point number.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose the currency, accepted decimal precision, rounding rule, minimum, and
maximum on the server. Never infer currency only from the user&amp;rsquo;s locale.&lt;/p>
&lt;h2 id="submit-the-entered-decimal-text">Submit the entered decimal text&lt;a class="td-heading-self-link" href="#submit-the-entered-decimal-text" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/invoices&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Amount in EUR
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;amount&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">inputmode&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;decimal&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">autocomplete&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;off&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">required&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;currency&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;hidden&amp;#34;&lt;/span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;EUR&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.amount&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ errors.amount }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Create invoice&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Parse the amount with a decimal or money type, validate its scale, and store
minor units or an exact decimal together with the currency. Return formatted
display text separately from the canonical value when needed.&lt;/p></description></item><item><title>Submit dates and times with an explicit time zone</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/dates-time-zones/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/dates-time-zones/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A date or appointment moves by a day or hour when users and servers use different
time zones.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Decide whether each value is a calendar date, a local wall-clock time, or an exact
instant. These are different domain values and need different storage rules.&lt;/p>
&lt;h2 id="send-the-local-value-and-zone-together">Send the local value and zone together&lt;a class="td-heading-self-link" href="#send-the-local-value-and-zone-together" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/appointments&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Local start
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;localStart&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;datetime-local&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Time zone
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;timeZone&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">option&lt;/span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;Europe/Riga&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Europe/Riga&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">option&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">select&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.localStart&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ errors.localStart }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Schedule&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Resolve local time with an IANA zone, reject nonexistent daylight-saving times,
and define how ambiguous times are chosen. Store exact instants in UTC while
retaining the zone when future local scheduling depends on it.&lt;/p></description></item><item><title>Keep identifiers as opaque strings</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/opaque-identifiers/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/opaque-identifiers/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A large numeric ID is rounded in JavaScript or application code starts depending
on structure that should be private to the server.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Define public identifiers as strings even when the database uses numbers. Treat
them as labels, not values for arithmetic or ordering.&lt;/p>
&lt;h2 id="submit-the-identifier-unchanged">Submit the identifier unchanged&lt;a class="td-heading-self-link" href="#submit-the-identifier-unchanged" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/invitations&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;accountId&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;hidden&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;acct_9007199254740993&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Email &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Invite&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Accept and return the identifier as a string. Validate its syntax, then authorize
the referenced resource independently. An unguessable ID is not permission.&lt;/p></description></item><item><title>Revalidate a cached response with ETag</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/conditional-cache/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/conditional-cache/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The browser repeatedly downloads a response that rarely changes.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Confirm the request is safe and cacheable. Decide whether the representation is
public, user-specific, or private before choosing cache headers.&lt;/p>
&lt;h2 id="let-http-perform-revalidation">Let HTTP perform revalidation&lt;a class="td-heading-self-link" href="#let-http-perform-revalidation" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Return a stable strong or weak &lt;code>ETag&lt;/code> with the representation. On a later request,
compare &lt;code>If-None-Match&lt;/code> and return &lt;code>304&lt;/code> without a body when it still matches.
Normal navigation and standards-based HTTP clients can then reuse cached bytes.&lt;/p></description></item><item><title>Keep a useful page during planned maintenance</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/maintenance-mode/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/maintenance-mode/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A deployment or dependency outage turns the application into an indefinite
spinner, proxy error, or misleading authentication failure.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Prepare a small server-rendered maintenance page that does not depend on the
database or application service being maintained.&lt;/p>
&lt;h2 id="return-the-correct-temporary-status">Return the correct temporary status&lt;a class="td-heading-self-link" href="#return-the-correct-temporary-status" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use &lt;code>503 Service Unavailable&lt;/code> and a realistic &lt;code>Retry-After&lt;/code> header. Explain what
is unavailable, whether existing data is safe, and when the user should retry.
Keep status and support links on dependencies that remain available.&lt;/p></description></item><item><title>Return users safely after sign-in</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/safe-redirect/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/safe-redirect/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The login flow accepts an arbitrary return URL, allowing attackers to send users
from a trusted sign-in page to a malicious site.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Prefer a server-side return target stored in the session. If a destination must
travel through the form, restrict it to known local routes or an allowlist.&lt;/p>
&lt;h2 id="submit-a-local-destination">Submit a local destination&lt;a class="td-heading-self-link" href="#submit-a-local-destination" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">action&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/login&amp;#34;&lt;/span> &lt;span style="color:#c4a000">method&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;post&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/login&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;return_to&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;hidden&amp;#34;&lt;/span> &lt;span style="color:#c4a000">value&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/orders&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Email &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">autocomplete&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;username&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Password
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;password&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;password&amp;#34;&lt;/span> &lt;span style="color:#c4a000">autocomplete&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;current-password&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Sign in&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Resolve the destination against an allowlist or accept only normalized local
paths. Reject protocol-relative URLs, encoded scheme tricks, control characters,
and destinations outside the application.&lt;/p></description></item><item><title>Return one safe error shape</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/error-envelope/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/error-envelope/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Every endpoint returns errors differently, so forms contain endpoint-specific
parsing and unexpected failures leak internal details.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Define a small envelope with a safe message, optional field errors, a stable code,
and a request ID. Keep HTTP status as the primary category.&lt;/p>
&lt;h2 id="bind-predictable-members">Bind predictable members&lt;a class="td-heading-self-link" href="#bind-predictable-members" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/profile&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;error = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Display name
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;name&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;error.fields.name&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ error.fields.name }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;error.message&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;alert&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ error.message }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;error.requestId&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Support code: {{ error.requestId }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Save&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Keep the envelope stable across &lt;code>401&lt;/code>, &lt;code>403&lt;/code>, &lt;code>409&lt;/code>, &lt;code>422&lt;/code>, &lt;code>429&lt;/code>, and &lt;code>5xx&lt;/code>, but
preserve those statuses. Use machine codes only for behavior the client actually
needs; do not mirror exception class names.&lt;/p></description></item><item><title>Make full-page and fragment responses explicit</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/content-negotiation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/content-negotiation/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The same URL serves normal navigation and an enhanced region update, but the
server sometimes returns a full page where a fragment is expected.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Define an explicit request policy using &lt;code>Accept&lt;/code>, a documented request header, or
separate routes. Do not infer intent from fragile user-agent checks.&lt;/p>
&lt;h2 id="keep-normal-navigation-available">Keep normal navigation available&lt;a class="td-heading-self-link" href="#keep-normal-navigation-available" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">href&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#orders&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;innerHTML&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Refresh orders
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders&amp;#34;&lt;/span> &lt;span style="color:#c4a000">aria-live&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;polite&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Current orders appear here.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Return a complete document for normal navigation and a valid application-owned
fragment for the enhanced request. Set &lt;code>Content-Type&lt;/code>, cache variation, and error
responses consistently for both representations.&lt;/p></description></item><item><title>Render user-authored rich text safely</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/rich-text/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/rich-text/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Users can author formatted content, but inserting their HTML as an AngularTS
fragment could compile attacker-controlled directives or executable markup.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose a maintained allowlist sanitizer and a deliberately small formatting
policy. Sanitize on the server before storage or rendering, not only in the browser.&lt;/p>
&lt;h2 id="keep-content-inside-an-application-owned-shell">Keep content inside an application-owned shell&lt;a class="td-heading-self-link" href="#keep-content-inside-an-application-owned-shell" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">header&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h1&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ post.title }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h1&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">header&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;post-body&amp;#34;&lt;/span> &lt;span style="color:#c4a000">class&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;rich-text&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> SERVER_RENDERED_SANITIZED_CONTENT
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The shell may use AngularTS bindings. The user-authored body is sanitized content,
not a template and not a source of directives.&lt;/p></description></item><item><title>Add Content Security Policy in report-only mode</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/content-security-policy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/content-security-policy/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The application has no browser policy limiting where scripts, styles, frames, and
connections may come from.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Inventory real production resources and choose a report endpoint that removes
sensitive URL and user data before storage.&lt;/p>
&lt;h2 id="start-by-observing">Start by observing&lt;a class="td-heading-self-link" href="#start-by-observing" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Send &lt;code>Content-Security-Policy-Report-Only&lt;/code> from the server. Begin with narrow
directives for &lt;code>default-src&lt;/code>, &lt;code>script-src&lt;/code>, &lt;code>style-src&lt;/code>, &lt;code>img-src&lt;/code>, &lt;code>font-src&lt;/code>,
&lt;code>connect-src&lt;/code>, &lt;code>frame-ancestors&lt;/code>, &lt;code>base-uri&lt;/code>, and &lt;code>form-action&lt;/code>. Use nonces or
hashes for deliberate inline content instead of broad unsafe allowances.&lt;/p></description></item><item><title>Harden an authentication session cookie</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/session-cookie/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/session-cookie/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Authentication state is readable by browser scripts or sent more broadly than
the application requires.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use the server framework&amp;rsquo;s maintained session implementation. Store only an opaque
session identifier in the browser, not authorization state or personal data.&lt;/p>
&lt;h2 id="set-the-cookie-at-the-server">Set the cookie at the server&lt;a class="td-heading-self-link" href="#set-the-cookie-at-the-server" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use &lt;code>Secure&lt;/code>, &lt;code>HttpOnly&lt;/code>, and an appropriate &lt;code>SameSite&lt;/code> value. Keep &lt;code>Path&lt;/code> and
&lt;code>Domain&lt;/code> as narrow as the deployment allows. Rotate the session after sign-in and
privilege changes, and expire it on logout.&lt;/p></description></item><item><title>Build a password-manager-friendly sign-in form</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/password-form/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/password-form/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Custom sign-in controls prevent password managers, keyboard submission, or browser
security features from recognizing the form.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use a normal server &lt;code>POST&lt;/code> endpoint over HTTPS. Keep labels, control names, and a
submit button in the document.&lt;/p>
&lt;h2 id="use-standard-autocomplete-semantics">Use standard autocomplete semantics&lt;a class="td-heading-self-link" href="#use-standard-autocomplete-semantics" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">action&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/login&amp;#34;&lt;/span> &lt;span style="color:#c4a000">method&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;post&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/login&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Email
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">autocomplete&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;username&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Password
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;password&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;password&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">autocomplete&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;current-password&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">required&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.message&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;alert&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ errors.message }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Sign in&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use a generic authentication error, rate-limit abuse, rotate the session after
success, and keep account recovery separate. New-password forms use
&lt;code>autocomplete=&amp;quot;new-password&amp;quot;&lt;/code>.&lt;/p></description></item><item><title>Keep secrets out of errors and logs</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/secret-redaction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/secret-redaction/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Request bodies, headers, URLs, or exceptions can copy credentials and personal
data into browser errors and long-lived logs.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Classify credentials and sensitive fields. Define allowlisted log fields instead
of trying to redact an unlimited set after serialization.&lt;/p>
&lt;h2 id="show-only-a-safe-support-reference">Show only a safe support reference&lt;a class="td-heading-self-link" href="#show-only-a-safe-support-reference" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/connections&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;connectionError = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>API key &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;apiKey&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;password&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Connect&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;connectionError&amp;#34;&lt;/span> &lt;span style="color:#c4a000">role&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;alert&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Connection failed. Support code: {{ connectionError.requestId }}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Never return or log the submitted key. Log an allowlisted operation name, safe
resource ID, status, duration, and request ID. Redact downstream exception data
before it crosses service boundaries.&lt;/p></description></item><item><title>Focus the first field rejected by the server</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/focus-first-error/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/focus-first-error/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server returns validation errors below the visible area and keyboard users do
not know which control needs attention.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Expose important controls with &lt;code>ng-el&lt;/code> and return field errors using control names.
Focus only after the failed response, not while the user is typing.&lt;/p>
&lt;h2 id="focus-a-known-field-after-rejection">Focus a known field after rejection&lt;a class="td-heading-self-link" href="#focus-a-known-field-after-rejection" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/el/el.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/profile&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res; emailInput.focus()&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Email
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">ng-el&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;emailInput&amp;#34;&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors.email&amp;#34;&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email-error&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ errors.email }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Save profile&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For several fields, let the response handler choose the first rejected control in
document order. Keep the visible message associated with its input.&lt;/p></description></item><item><title>Turn an empty result into the next action</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/empty-state/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/empty-state/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>An empty collection renders a blank region that looks broken and gives no path
forward.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Separate first-use emptiness, filter emptiness, permission limits, loading, and
request failure. They require different messages and actions.&lt;/p>
&lt;h2 id="render-the-empty-case-deliberately">Render the empty case deliberately&lt;a class="td-heading-self-link" href="#render-the-empty-case-deliberately" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;projects.length &amp;gt; 0&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span> &lt;span style="color:#c4a000">ng-repeat&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;project in projects&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>{{ project.name }}&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;projects.length === 0&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h2&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>No projects yet&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h2&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Create the first project to organize this work.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span> &lt;span style="color:#c4a000">href&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/projects/new&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Create a project&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Return an empty collection as a successful result. Do not use &lt;code>404&lt;/code> for a valid
collection with no records. Preserve active filters so the empty explanation can
offer clearing them when appropriate.&lt;/p></description></item><item><title>Preserve focus when replacing server HTML</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/focus-after-swap/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/focus-after-swap/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A fragment replacement removes the focused element or leaves keyboard users
outside the newly displayed content.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose whether focus should remain on a stable trigger or move to the result. Add
a programmatically focusable heading only when moving focus is useful.&lt;/p>
&lt;h2 id="keep-the-target-stable-and-focus-its-heading">Keep the target stable and focus its heading&lt;a class="td-heading-self-link" href="#keep-the-target-stable-and-focus-its-heading" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/el/el.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-get&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/account/summary&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">data-target&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;#summary-body&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">swap&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;innerHTML&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">on-success&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;summaryHeading.focus()&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Load summary
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h2&lt;/span> &lt;span style="color:#c4a000">ng-el&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;summaryHeading&amp;#34;&lt;/span> &lt;span style="color:#c4a000">tabindex&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;-1&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Account summary&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h2&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;summary-body&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Summary not loaded.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">div&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">article&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Return only the body fragment so the stable heading and its &lt;code>ng-el&lt;/code> reference are
not removed. Use valid application-owned HTML.&lt;/p></description></item><item><title>Deliver a feature flag with the server page</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/feature-flag/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/feature-flag/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The page waits for a second request before deciding which small interface variation
to show, causing flicker and inconsistent first rendering.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Evaluate the flag on the server using the authenticated request and rollout policy.
Treat the result as presentation, never as permission.&lt;/p>
&lt;h2 id="initialize-the-evaluated-result">Initialize the evaluated result&lt;a class="td-heading-self-link" href="#initialize-the-evaluated-result" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts, src/directive/init/init.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">ng-init&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;flags = { compactCheckout: false }&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;flags.compactCheckout&amp;#34;&lt;/span> &lt;span style="color:#c4a000">href&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/checkout/compact&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Use compact checkout
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;!flags.compactCheckout&amp;#34;&lt;/span> &lt;span style="color:#c4a000">href&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/checkout&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Continue to checkout
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">a&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Render the evaluated boolean into the server template. Do not expose targeting
rules, experiment secrets, or unrelated flags.&lt;/p></description></item><item><title>Record who changed sensitive data</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/audit-trail/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/audit-trail/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A sensitive record changed, but the application cannot explain who changed what,
when, or through which operation.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Define which domain actions require audit history, who may read it, retention,
redaction, and the difference between audit events and diagnostic logs.&lt;/p>
&lt;h2 id="ask-for-context-when-the-domain-needs-it">Ask for context when the domain needs it&lt;a class="td-heading-self-link" href="#ask-for-context-when-the-domain-needs-it" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/docs-examples/cookbook-patterns.test.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span> &lt;span style="color:#c4a000">ng-post&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/api/accounts/42/suspend&amp;#34;&lt;/span> &lt;span style="color:#c4a000">on-error&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;errors = $res&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Reason for suspension
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">textarea&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;reason&amp;#34;&lt;/span> &lt;span style="color:#c4a000">required&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">textarea&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Suspend account&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="server-contract">Server contract&lt;a class="td-heading-self-link" href="#server-contract" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Derive actor, tenant, request ID, time, and affected resource on the server. Record
the domain action and safe before-and-after facts in the same transaction or a
reliable transactional outbox.&lt;/p></description></item><item><title>Roll out a request contract without breaking old pages</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/compatible-rollout/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/compatible-rollout/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A deployment changes a field or response shape while users still have pages,
workers, or tabs running code from the previous release.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Measure how long old clients and cached pages remain active. Identify producers,
consumers, integrations, queued jobs, and persisted data using the contract.&lt;/p>
&lt;h2 id="use-an-expand-and-contract-rollout">Use an expand-and-contract rollout&lt;a class="td-heading-self-link" href="#use-an-expand-and-contract-rollout" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>First make the server accept old and new requests. Then deploy clients that use
the new shape. Observe adoption and errors. Migrate stored data and background
producers. Remove old behavior only after the supported compatibility window.&lt;/p></description></item><item><title>Find a beginner recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-beginner-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-beginner-recipes/</guid><description>&lt;h2 id="start-here">Start here&lt;a class="td-heading-self-link" href="#start-here" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Work through these recipes in order until you reach the problem you need to solve.
Each one assumes only the earlier browser and HTML concepts.&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>What you need&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Inspect a running page&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/inspect-running-application/">Inspect the application&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Find an element&amp;rsquo;s scope&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/select-elements/">Select elements through the scope&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Include initial server data&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/server-data/">Pass data from the server&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Change element content or classes&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/update-dom/">Update the DOM&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Replace an element&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/replace-dom/">Replace DOM&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Render server HTML in a region&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/swap-server-html/">Swap server HTML&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>React to state&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/effects/">Run effects&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Handle browser and scope events&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/event-handling/">Handle events&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Submit user input&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/forms/">Build forms&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Call a JSON endpoint&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/rest/">Use REST services&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Keep the page useful without JavaScript&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/progressive-enhancement/">Enhance progressively&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Compare the server-driven approach&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/htmx-patterns/">Understand the HTMX similarity&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="choose-the-next-area">Choose the next area&lt;a class="td-heading-self-link" href="#choose-the-next-area" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Continue with the forms, HTTP, DOM, navigation, security, or performance finder
instead of reading the cookbook from top to bottom.&lt;/p></description></item><item><title>Find a form recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-form-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-form-recipes/</guid><description>&lt;h2 id="build-the-basic-flow">Build the basic flow&lt;a class="td-heading-self-link" href="#build-the-basic-flow" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Submit controls and display responses&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/forms/">Build forms&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Render named server errors&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/server-validation/">Show server validation&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Focus a rejected control&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/focus-first-error/">Focus the first error&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Upload and cancel a file&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/upload-cancel/">Upload with cancellation&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Search while typing&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/active-search/">Build active search&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Load one choice from another&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/dependent-selects/">Build dependent selects&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Save several steps&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/multi-step-form/">Build a multi-step form&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="protect-the-write">Protect the write&lt;a class="td-heading-self-link" href="#protect-the-write" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Protect a cookie-authenticated form&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/csrf-protected-form/">Send CSRF proof&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Prevent duplicate critical effects&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/idempotent-write/">Use an idempotency key&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Confirm permanent deletion&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/confirm-delete/">Confirm deletion&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Preserve another person&amp;rsquo;s edit&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/edit-conflict/">Handle edit conflicts&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Handle a uniqueness race&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/unique-race/">Return uniqueness errors&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="represent-input-correctly">Represent input correctly&lt;a class="td-heading-self-link" href="#represent-input-correctly" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Submit currency&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/money-values/">Send money safely&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Submit local time&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/dates-time-zones/">Send dates with zones&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Submit several records&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/bulk-action/">Apply a bulk action&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Build sign-in controls&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/password-form/">Support password managers&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Harden the session form&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/session-cookie/">Harden session cookies&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description></item><item><title>Find an HTTP recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-http-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-http-recipes/</guid><description>&lt;h2 id="define-the-response-first">Define the response first&lt;a class="td-heading-self-link" href="#define-the-response-first" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Choose status, body, and content type&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/http-response-contracts/">Design an HTTP response&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Keep error bodies predictable&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/error-envelope/">Use an error envelope&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Return a page or a fragment&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/content-negotiation/">Negotiate content explicitly&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Swap trusted server markup&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/safe-html-fragment/">Replace a region with server HTML&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="control-requests">Control requests&lt;a class="td-heading-self-link" href="#control-requests" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Recover from a failed read&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/retry-failed-read/">Offer manual retry&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Stop duplicate or stale requests&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/control-repeat-requests/">Control repeated requests&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Respect a server limit&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/rate-limit/">Handle rate limiting&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Move slow work out of the request&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/background-job/">Run a background job&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Avoid retransferring unchanged data&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/conditional-cache/">Revalidate with ETag&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Stream a generated file to disk&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/download-file/">Use a browser download&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="handle-deployment-boundaries">Handle deployment boundaries&lt;a class="td-heading-self-link" href="#handle-deployment-boundaries" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Call JSON services&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/rest/">Use REST services&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Serve a temporary outage&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/maintenance-mode/">Return maintenance mode&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Call another origin&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/cross-origin-request/">Configure cross-origin access&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description></item><item><title>Find a DOM recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-dom-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-dom-recipes/</guid><description>&lt;h2 id="wire-elements-to-scope">Wire elements to scope&lt;a class="td-heading-self-link" href="#wire-elements-to-scope" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Expose an element without querying&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/select-elements/">Select elements through scope&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Change text and classes&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/update-dom/">Update the DOM&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Replace a node&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/replace-dom/">Replace DOM&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Replace a region with server markup&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/swap-server-html/">Swap server HTML&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="build-common-interactions">Build common interactions&lt;a class="td-heading-self-link" href="#build-common-interactions" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Edit one record in place&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/inline-edit/">Build inline editing&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Remove a confirmed row&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/delete-row/">Delete a row&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Update before a request completes&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/optimistic-update/">Use an optimistic update&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Load a server-rendered dialog&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/server-dialog/">Open a server dialog&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="keep-updates-usable">Keep updates usable&lt;a class="td-heading-self-link" href="#keep-updates-usable" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Announce and focus request results&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/accessible-requests/">Make requests accessible&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Explain an empty collection&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/empty-state/">Design an empty state&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Keep focus after replacement&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/focus-after-swap/">Preserve focus after swaps&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description></item><item><title>Find a security recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-security-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-security-recipes/</guid><description>&lt;h2 id="protect-server-operations">Protect server operations&lt;a class="td-heading-self-link" href="#protect-server-operations" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Audit a complete interaction&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/secure-request/">Run the security audit&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Protect cookie-authenticated writes&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/csrf-protected-form/">Send CSRF proof&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Enforce current permissions&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/permission-denied/">Handle permission rejection&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Prevent duplicate critical writes&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/idempotent-write/">Use idempotency&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>End an authenticated session&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/logout/">Log out safely&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="protect-browser-content">Protect browser content&lt;a class="td-heading-self-link" href="#protect-browser-content" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Validate a return destination&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/safe-redirect/">Prevent open redirects&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Render user-authored formatting&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/rich-text/">Sanitize rich text&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Restrict executable resources&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/content-security-policy/">Deploy Content Security Policy&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Restrict session delivery&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/session-cookie/">Harden session cookies&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Remove credentials from diagnostics&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/secret-redaction/">Redact secrets&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="protect-destructive-actions">Protect destructive actions&lt;a class="td-heading-self-link" href="#protect-destructive-actions" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Confirm permanent removal&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/confirm-delete/">Confirm deletion&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Prefer a reversible operation&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/archive-restore/">Archive and restore&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description></item><item><title>Find a performance recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-performance-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-performance-recipes/</guid><description>&lt;h2 id="reduce-network-work">Reduce network work&lt;a class="td-heading-self-link" href="#reduce-network-work" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Avoid repeated unchanged reads&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/cached-reference-data/">Cache reference data&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Use HTTP validators&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/conditional-cache/">Revalidate with ETag&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Delay, throttle, or cancel requests&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/control-repeat-requests/">Control repeated requests&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Prefetch before a click&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/server-data/">Prefetch a result&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="reduce-rendering-work">Reduce rendering work&lt;a class="td-heading-self-link" href="#reduce-rendering-work" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Page a large collection&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/server-pagination/">Paginate on the server&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Load more near the viewport&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/infinite-scroll/">Build infinite scrolling&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>React to visibility&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-viewport/">Use viewport observation&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Keep simple reference data&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/caching/">Use caching&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="move-specialized-work">Move specialized work&lt;a class="td-heading-self-link" href="#move-specialized-work" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Receive incremental server changes&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-sse/">Use server-sent events&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Move CPU work off the main thread&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-worker/">Use a worker&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Run measured native computation&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-wasm/">Use WebAssembly&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Move slow server work out of a request&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/background-job/">Run a background job&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="reduce-shipped-javascript">Reduce shipped JavaScript&lt;a class="td-heading-self-link" href="#reduce-shipped-javascript" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>The measured runtime contains unused features&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/optimized-runtime-build/">Build a smaller production runtime&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description></item><item><title>Find a data correctness recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-data-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-data-recipes/</guid><description>&lt;h2 id="represent-values-correctly">Represent values correctly&lt;a class="td-heading-self-link" href="#represent-values-correctly" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Keep public IDs unchanged&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/opaque-identifiers/">Use opaque identifiers&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Preserve currency precision&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/money-values/">Submit money safely&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Preserve time meaning&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/dates-time-zones/">Send dates with zones&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Seed initial server values&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/server-data/">Pass server data&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="protect-concurrent-changes">Protect concurrent changes&lt;a class="td-heading-self-link" href="#protect-concurrent-changes" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Detect a stale edit&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/edit-conflict/">Handle edit conflicts&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Handle a unique constraint race&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/unique-race/">Return uniqueness errors&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Make a write repeatable&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/idempotent-write/">Use idempotency&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Report partial batch results&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/bulk-action/">Apply bulk actions&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="preserve-history-and-compatibility">Preserve history and compatibility&lt;a class="td-heading-self-link" href="#preserve-history-and-compatibility" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Keep useful cached records&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/cached-reference-data/">Cache reference data&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Keep state across an expired session&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/session-expiration/">Handle session expiration&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Record a sensitive change&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/audit-trail/">Write an audit trail&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Change a contract safely&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/compatible-rollout/">Use a compatible rollout&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description></item><item><title>Find a navigation recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-navigation-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-navigation-recipes/</guid><description>&lt;h2 id="start-with-server-navigation">Start with server navigation&lt;a class="td-heading-self-link" href="#start-with-server-navigation" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Keep forms useful before enhancement&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/progressive-enhancement/">Use progressive enhancement&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Preserve search in the address&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/url-filter/">Keep filters in the URL&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Preserve list navigation&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/server-pagination/">Paginate on the server&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Return safely after sign-in&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/safe-redirect/">Validate redirects&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="add-browser-owned-state-where-needed">Add browser-owned state where needed&lt;a class="td-heading-self-link" href="#add-browser-owned-state-where-needed" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Define application routes&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/routing/">Use the router&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Enter a state after sign-in&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/authentication/">Handle authentication&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Enter the next saved form step&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/multi-step-form/">Build a multi-step form&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Recover from an expired session&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/session-expiration/">Handle session expiration&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Enter a public state after logout&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/logout/">Log out safely&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description></item><item><title>Find an operations recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-operations-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-operations-recipes/</guid><description>&lt;h2 id="diagnose-a-request">Diagnose a request&lt;a class="td-heading-self-link" href="#diagnose-a-request" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Follow element, scope, request, and DOM&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/debug-http-interaction/">Debug an HTTP interaction&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Connect an error to server logs&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/request-id/">Show a request ID&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Keep credentials out of telemetry&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/secret-redaction/">Redact secrets&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Check a whole feature&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/ship-interaction/">Run the shipping check&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="operate-degraded-systems">Operate degraded systems&lt;a class="td-heading-self-link" href="#operate-degraded-systems" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Tell users when to retry&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/rate-limit/">Handle rate limits&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Move long work to a worker process&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/background-job/">Run a background job&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Serve a planned outage&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/maintenance-mode/">Return maintenance mode&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="change-production-safely">Change production safely&lt;a class="td-heading-self-link" href="#change-production-safely" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Deliver a rollout decision&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/feature-flag/">Use server feature flags&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Explain a sensitive state change&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/audit-trail/">Record an audit trail&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Support mixed release versions&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/compatible-rollout/">Roll contracts out compatibly&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description></item><item><title>Find an advanced browser recipe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/find-advanced-recipes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/find-advanced-recipes/</guid><description>&lt;h2 id="react-to-browser-and-scope-changes">React to browser and scope changes&lt;a class="td-heading-self-link" href="#react-to-browser-and-scope-changes" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Run cleanup-aware reactions&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/effects/">Use effects&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Handle browser and scope events&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/event-handling/">Handle events&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>React to element visibility&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-viewport/">Observe the viewport&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Stream server updates&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-sse/">Use server-sent events&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Send and receive live messages&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-websocket/">Use WebSocket&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="add-specialized-execution">Add specialized execution&lt;a class="td-heading-self-link" href="#add-specialized-execution" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Move computation off the main thread&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-worker/">Use a worker&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Call measured native computation&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-wasm/">Use WebAssembly&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Remove unused framework code&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/optimized-runtime-build/">Build a smaller runtime&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Cancel a large upload&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/upload-cancel/">Control an upload&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Call an API on another origin&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/cross-origin-request/">Configure cross-origin access&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="build-specialized-interaction">Build specialized interaction&lt;a class="td-heading-self-link" href="#build-specialized-interaction" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Append results near the viewport&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/infinite-scroll/">Build infinite scrolling&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Update before the server responds&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/optimistic-update/">Use optimistic updates&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Load a modal from the server&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/server-dialog/">Open a server dialog&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Render sanitized authored content&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/rich-text/">Handle rich text&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="integrate-another-framework">Integrate another framework&lt;a class="td-heading-self-link" href="#integrate-another-framework" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Problem&lt;/th>
 &lt;th>Recipe&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Choose an integration boundary&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/framework-integration/">Choose a bridge&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Publish transient cross-root messages&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/framework-event-bus/">Use the event bus&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Read reflected web-component state&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/framework-observe/">Observe Fluent UI attributes&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Share current reactive state&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/framework-model/">Use an application model&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table></description></item><item><title>Exchange live messages with WebSocket</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-websocket/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/advanced-websocket/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The browser must send messages while the server pushes new messages over the
same long-running connection. Repeated HTTP requests or SSE only solve half of
that conversation.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use WebSocket only when both sides need to send independently. Prefer SSE when
the browser only receives updates, and ordinary HTTP when messages are
infrequent.&lt;/p>
&lt;p>AngularTS exposes
&lt;a href="../../../typedoc/types/WebSocketService.html">&lt;code>WebSocketService&lt;/code>&lt;/a>,
&lt;a href="../../../typedoc/interfaces/WebSocketConfig.html">&lt;code>WebSocketConfig&lt;/code>&lt;/a>, and the
managed
&lt;a href="../../../typedoc/interfaces/WebSocketConnection.html">&lt;code>WebSocketConnection&lt;/code>&lt;/a>.
The managed connection handles message decoding, retry policy, heartbeats, and
explicit cleanup.&lt;/p></description></item><item><title>Integrate AngularTS with another framework</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/framework-integration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/framework-integration/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>An AngularTS module must coexist with a web component or another UI framework
without both runtimes fighting over the same DOM and state.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Give each framework its own root element. One framework owns rendering and
cleanup inside that root. Integrate at the root boundary instead of compiling
the same subtree twice.&lt;/p>
&lt;h2 id="choose-the-smallest-bridge">Choose the smallest bridge&lt;a class="td-heading-self-link" href="#choose-the-smallest-bridge" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>What crosses the boundary&lt;/th>
 &lt;th>Use&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>A transient message that something happened&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/framework-event-bus/">The event bus&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>State reflected by a custom element attribute&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/framework-observe/">&lt;code>ng-observe&lt;/code>&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Current domain state needed by both sides&lt;/td>
 &lt;td>&lt;a href="https://angular-wave.github.io/angular.ts/docs/cookbook/framework-model/">A shared model&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Use browser custom events directly when one element and its immediate owner are
the only participants. Use the event bus when producers and consumers should not
know each other. Use a model when consumers need the current value, not only a
notification that it changed.&lt;/p></description></item><item><title>Send messages across framework roots</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/framework-event-bus/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/framework-event-bus/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A component in another framework needs to notify an AngularTS module without
holding its controller, scope, or DOM implementation.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Name the event after something that happened, such as &lt;code>product:selected&lt;/code>. Keep
the payload small and define its shape at the integration boundary.&lt;/p>
&lt;h2 id="publish-outside-and-subscribe-inside-angularts">Publish outside and subscribe inside AngularTS&lt;a class="td-heading-self-link" href="#publish-outside-and-subscribe-inside-angularts" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/services/event-bus/event-bus.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">app&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">angular&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">createModule&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;catalog&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">[]);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">app&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;SelectionController&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#39;$eventBus&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#39;$scope&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">function&lt;/span> &lt;span style="color:#000">SelectionController&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">$eventBus&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">$scope&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">selected&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">undefined&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">$eventBus&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">subscribe&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#39;product:selected&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">product&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">selected&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">product&lt;/span>&lt;span style="color:#000;font-weight:bold">),&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">$scope&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">]);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">externalCatalog&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">onSelected&lt;/span>&lt;span style="color:#000;font-weight:bold">((&lt;/span>&lt;span style="color:#000">product&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">angular&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">eventBus&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">publish&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;product:selected&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">product&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The injected &lt;code>$eventBus&lt;/code> and &lt;code>angular.eventBus&lt;/code> expose the same application bus.
Delivery is asynchronous through a microtask and listeners run in subscription
order. Passing a scope as the subscription context removes the listener when the
scope is destroyed and skips queued delivery to that destroyed scope.&lt;/p></description></item><item><title>Read Fluent UI custom-element state with ng-observe</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/framework-observe/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/framework-observe/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A custom element owns its internal behavior and reports current state by
changing an attribute. AngularTS needs that value without taking over the
element&amp;rsquo;s DOM.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Confirm the component reflects the required state to an attribute. &lt;code>ng-observe&lt;/code>
watches attributes with &lt;code>MutationObserver&lt;/code>; it does not poll JavaScript-only
properties.&lt;/p>
&lt;h2 id="observe-the-fluent-ui-attribute">Observe the Fluent UI attribute&lt;a class="td-heading-self-link" href="#observe-the-fluent-ui-attribute" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>This example is taken from the repository&amp;rsquo;s Fluent UI observe demo.&lt;/p></description></item><item><title>Share current state through an application model</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/framework-model/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/framework-model/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Two framework roots need the current shopping-cart state. Sending only
&lt;code>item:added&lt;/code> events makes late consumers reconstruct state and handle missed
messages.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Choose one owner for the model and its mutations. Retrieve the same registered
model from the AngularTS application injector instead of copying it into each
framework store.&lt;/p>
&lt;h2 id="register-one-shopping-cart-model">Register one shopping-cart model&lt;a class="td-heading-self-link" href="#register-one-shopping-cart-model" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;!-- tested-by: src/core/di/ng-module/ng-module.spec.ts -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">shop&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">angular&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">createModule&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;shop&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">[]);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">shop&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">model&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;cart&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">()&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">({&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">items&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">[],&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">currency&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;EUR&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}));&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">shop&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;CartSummary&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#39;cart&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">function&lt;/span> &lt;span style="color:#000">CartSummary&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">cart&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">cart&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">cart&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">]);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Inject &lt;code>cart&lt;/code> into AngularTS controllers, services, or component views. A
non-Angular root can retrieve the same instance from the injector associated
with the shared application root.&lt;/p></description></item><item><title>Build a smaller production runtime</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/optimized-runtime-build/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/optimized-runtime-build/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The production JavaScript bundle is larger than its measured budget even though
the application uses only a small part of AngularTS. Importing the full runtime
ships directives and services that this page never uses.&lt;/p>
&lt;h2 id="before-you-start">Before you start&lt;a class="td-heading-self-link" href="#before-you-start" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Optimize the server response, images, fonts, and application code before
maintaining a custom runtime. Use this recipe only after a production bundle
report shows that unused AngularTS features are material.&lt;/p></description></item><item><title>Add behavior to server-rendered HTML</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/style-guide/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/style-guide/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>The server already renders a useful page. One part needs client-side behavior,
but the page should still work when JavaScript fails or loads slowly.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Keep navigation, forms, and initial content in HTML. Put AngularTS on the
smallest element that needs it.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">main&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h1&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Search products&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">h1&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">action&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/products&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">method&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;get&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-app&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;catalog&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#c4a000">ng-controller&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;SearchController as search&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span> &lt;span style="color:#c4a000">for&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;query&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Search&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">label&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">id&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;query&amp;#34;&lt;/span> &lt;span style="color:#c4a000">name&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;q&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;search.query&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span> &lt;span style="color:#c4a000">aria-live&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;polite&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-bind&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;search.message()&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">span&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;submit&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Search&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">form&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">main&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">app&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">angular&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">createModule&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;catalog&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">[]);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">app&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;SearchController&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#204a87;font-weight:bold">function&lt;/span> &lt;span style="color:#000">SearchController&lt;/span>&lt;span style="color:#000;font-weight:bold">()&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">query&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">message&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000;font-weight:bold">()&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">count&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">query&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">trim&lt;/span>&lt;span style="color:#000;font-weight:bold">().&lt;/span>&lt;span style="color:#000">length&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#000">count&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">===&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">?&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;Enter a search term&amp;#39;&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000">count&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">+&lt;/span> &lt;span style="color:#4e9a06">&amp;#39; characters&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">};&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The form remains a normal &lt;code>GET&lt;/code> request. AngularTS adds feedback, but does not
own navigation or the initial result page.&lt;/p></description></item><item><title>Make a component view reactive</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/reactive-state/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/reactive-state/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A component changes its controller state, but a value in its component view
stays frozen at the initial value.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Pass a reader function for values that can change.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ts" data-lang="ts">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">import&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span> &lt;span style="color:#000">button&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">output&lt;/span> &lt;span style="color:#000;font-weight:bold">}&lt;/span> &lt;span style="color:#204a87;font-weight:bold">from&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;@angular-wave/angular.ts&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">class&lt;/span> &lt;span style="color:#000">CounterController&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">count&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">app&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">angular&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">createModule&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;counter&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">[]);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">app&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">component&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">CounterController&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;counter&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">controller&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">CounterController&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">view&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">({&lt;/span> &lt;span style="color:#000">controller&lt;/span> &lt;span style="color:#000;font-weight:bold">})&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">button&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;button&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">onclick&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">()&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">count&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">+=&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#39;Add&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">),&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">output&lt;/span>&lt;span style="color:#000;font-weight:bold">(()&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">count&lt;/span>&lt;span style="color:#000;font-weight:bold">),&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">];&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Use &lt;code>() =&amp;gt; controller.count&lt;/code>, not &lt;code>controller.count&lt;/code>, for the changing child.&lt;/p>
&lt;h2 id="why-this-works">Why this works&lt;a class="td-heading-self-link" href="#why-this-works" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>&lt;code>controller.count&lt;/code> reads the value while the view is being created. The view
receives one number and has nothing to read later.&lt;/p></description></item><item><title>Keep repeated rows stable</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/collections/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/collections/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Refreshing a collection replaces every object. &lt;code>ng-repeat&lt;/code> then rebuilds rows,
which loses focus, selection, local element state, and animation continuity.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Reconcile incoming records with the existing objects before replacing the
collection.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ts" data-lang="ts">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">interface&lt;/span> &lt;span style="color:#000">User&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">id&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">string&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">name&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">string&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">function&lt;/span> &lt;span style="color:#000">reconcileUsers&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">current&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">User&lt;/span>&lt;span style="color:#000;font-weight:bold">[],&lt;/span> &lt;span style="color:#000">incoming&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">User&lt;/span>&lt;span style="color:#000;font-weight:bold">[])&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000">User&lt;/span>&lt;span style="color:#000;font-weight:bold">[]&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">existing&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">new&lt;/span> &lt;span style="color:#000">Map&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">current&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">map&lt;/span>&lt;span style="color:#000;font-weight:bold">((&lt;/span>&lt;span style="color:#000">user&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#000">user&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">id&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">user&lt;/span>&lt;span style="color:#000;font-weight:bold">]));&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#000">incoming&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">map&lt;/span>&lt;span style="color:#000;font-weight:bold">((&lt;/span>&lt;span style="color:#000">next&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">user&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">existing&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">get&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">next&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">id&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">if&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">!&lt;/span>&lt;span style="color:#000">user&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#000">next&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87">Object&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">assign&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">user&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">next&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#000">user&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Use the reconciled array after a refresh:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ts" data-lang="ts">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">users&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">reconcileUsers&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">users&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">response&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">data&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Render it normally:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span> &lt;span style="color:#c4a000">ng-repeat&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;user in users&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">input&lt;/span> &lt;span style="color:#c4a000">ng-model&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;user.name&amp;#34;&lt;/span> &lt;span style="color:#000;font-weight:bold">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="why-this-works">Why this works&lt;a class="td-heading-self-link" href="#why-this-works" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>&lt;code>ng-repeat&lt;/code> tracks objects by identity. Reusing the object for the same &lt;code>id&lt;/code>
lets AngularTS reuse that row. New records get new rows, removed records lose
their rows, and existing records keep their DOM.&lt;/p></description></item><item><title>Stop hidden UI from doing work</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/rendering/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/rendering/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A closed panel still runs watchers, observers, timers, or network work because
CSS hides it without removing it.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Use &lt;code>ng-if&lt;/code> when closing the UI should destroy it.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;button&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;detailsOpen = !detailsOpen&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Toggle details
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">account-details&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;detailsOpen&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">account-details&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Use &lt;code>ng-show&lt;/code> only when the DOM and its state must stay alive:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">video-player&lt;/span> &lt;span style="color:#c4a000">ng-show&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;playerOpen&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">video-player&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="why-this-works">Why this works&lt;a class="td-heading-self-link" href="#why-this-works" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>&lt;code>ng-if&lt;/code> removes the subtree and destroys its child scope. Reopening it creates a
fresh subtree.&lt;/p></description></item><item><title>Ignore stale request results</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/network-and-routing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/network-and-routing/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A user searches for &lt;code>cat&lt;/code>, then quickly searches for &lt;code>caterpillar&lt;/code>. The second
request finishes first. The slower &lt;code>cat&lt;/code> response arrives later and replaces the
correct results.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Give each request a sequence number. Apply a response only when it belongs to
the newest request.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">app&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;SearchController&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#204a87;font-weight:bold">function&lt;/span> &lt;span style="color:#000">SearchController&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">$http&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">let&lt;/span> &lt;span style="color:#000">latestRequest&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">results&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000;font-weight:bold">[];&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">loading&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">false&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">error&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">search&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">async&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">query&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">request&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">++&lt;/span>&lt;span style="color:#000">latestRequest&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">loading&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">error&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">try&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">response&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">await&lt;/span> &lt;span style="color:#000">$http&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">get&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;/api/search&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">params&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span> &lt;span style="color:#000">q&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000">query&lt;/span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">if&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">request&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">===&lt;/span> &lt;span style="color:#000">latestRequest&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">results&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">response&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">data&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span> &lt;span style="color:#204a87;font-weight:bold">catch&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">error&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">if&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">request&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">===&lt;/span> &lt;span style="color:#000">latestRequest&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">error&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;Search failed&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span> &lt;span style="color:#204a87;font-weight:bold">finally&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">if&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">request&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">===&lt;/span> &lt;span style="color:#000">latestRequest&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">loading&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">false&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">};&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="why-this-works">Why this works&lt;a class="td-heading-self-link" href="#why-this-works" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Network responses can arrive in any order. The sequence number records which
request currently owns the screen. Older requests may finish, but they cannot
change results, errors, or loading state.&lt;/p></description></item><item><title>Clean up browser resources</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/lifecycle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/lifecycle/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A component adds a browser listener or timer. After navigation or &lt;code>ng-if&lt;/code>
removes the component, the callback still runs and keeps old state in memory.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Create the resource inside the component view and register its cleanup at the
same time.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ts" data-lang="ts">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">import&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span> &lt;span style="color:#000">time&lt;/span> &lt;span style="color:#000;font-weight:bold">}&lt;/span> &lt;span style="color:#204a87;font-weight:bold">from&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;@angular-wave/angular.ts&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">class&lt;/span> &lt;span style="color:#000">ClockController&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">now&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">new&lt;/span> &lt;span style="color:#204a87">Date&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">app&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">component&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ClockController&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;clock&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">controller&lt;/span>: &lt;span style="color:#204a87;font-weight:bold">ClockController&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">view&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#000;font-weight:bold">({&lt;/span> &lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#000">onDestroy&lt;/span> &lt;span style="color:#000;font-weight:bold">})&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">timer&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87">window&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">setInterval&lt;/span>&lt;span style="color:#000;font-weight:bold">(()&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">now&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">new&lt;/span> &lt;span style="color:#204a87">Date&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#000">_000&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">onDestroy&lt;/span>&lt;span style="color:#000;font-weight:bold">(()&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87">window&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">clearInterval&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">timer&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">return&lt;/span> &lt;span style="color:#000">time&lt;/span>&lt;span style="color:#000;font-weight:bold">(()&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">now&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">toLocaleTimeString&lt;/span>&lt;span style="color:#000;font-weight:bold">());&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">},&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For browser listeners, an &lt;code>AbortController&lt;/code> keeps several listeners under one
cleanup:&lt;/p></description></item><item><title>Find the slow part of an interaction</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/measure-before-optimizing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/measure-before-optimizing/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>An interaction feels slow, but changing watchers or rendering code without a
trace only moves work around.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Record one interaction and optimize the longest measured task.&lt;/p>
&lt;ol>
&lt;li>Reproduce the problem with realistic data and a production build.&lt;/li>
&lt;li>Open the browser Performance panel.&lt;/li>
&lt;li>Start recording immediately before the interaction.&lt;/li>
&lt;li>Stop after the screen reaches its final state.&lt;/li>
&lt;li>Find the longest main-thread task or network wait.&lt;/li>
&lt;li>Expand that task until you can name the function, layout, paint, or request
responsible.&lt;/li>
&lt;li>Change one cause and record the same interaction again.&lt;/li>
&lt;/ol>
&lt;p>Add marks when the trace does not show where application work starts:&lt;/p></description></item><item><title>Render every request state</title><link>https://angular-wave.github.io/angular.ts/docs/cookbook/best-practices/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://angular-wave.github.io/angular.ts/docs/cookbook/best-practices/</guid><description>&lt;h2 id="problem">Problem&lt;a class="td-heading-self-link" href="#problem" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>A request-driven screen shows stale content during loading, treats an empty
result as an error, or leaves the loading indicator visible after failure.&lt;/p>
&lt;h2 id="recipe">Recipe&lt;a class="td-heading-self-link" href="#recipe" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>Model request status separately from its data.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">app&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">controller&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;OrdersController&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span> &lt;span style="color:#204a87;font-weight:bold">function&lt;/span> &lt;span style="color:#000">OrdersController&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">$http&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">status&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;idle&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">orders&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000;font-weight:bold">[];&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">load&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">async&lt;/span> &lt;span style="color:#000;font-weight:bold">()&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">status&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;loading&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">try&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">const&lt;/span> &lt;span style="color:#000">response&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">await&lt;/span> &lt;span style="color:#000">$http&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">get&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;/api/orders&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">orders&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#000">response&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">data&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">status&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">orders&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">length&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">===&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">?&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;empty&amp;#39;&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">:&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;ready&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span> &lt;span style="color:#204a87;font-weight:bold">catch&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">error&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">this&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">status&lt;/span> &lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span> &lt;span style="color:#4e9a06">&amp;#39;error&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">};&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Render each state once:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span> &lt;span style="color:#c4a000">aria-live&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;polite&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders.status === &amp;#39;loading&amp;#39;&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>Loading orders...&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders.status === &amp;#39;error&amp;#39;&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-click&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders.load()&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Try again
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">button&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders.status === &amp;#39;empty&amp;#39;&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>No orders yet.&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">p&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span> &lt;span style="color:#c4a000">ng-if&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;orders.status === &amp;#39;ready&amp;#39;&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span> &lt;span style="color:#c4a000">ng-repeat&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;order in orders.orders&amp;#34;&lt;/span> &lt;span style="color:#c4a000">ng-bind&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;order.number&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">li&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ul&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">&amp;lt;/&lt;/span>&lt;span style="color:#204a87;font-weight:bold">section&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="why-this-works">Why this works&lt;a class="td-heading-self-link" href="#why-this-works" aria-label="Heading self-link">&lt;/a>&lt;/h2>
&lt;p>One status value prevents impossible combinations such as loading and error
appearing together. Empty data is a successful response, so it gets its own
state instead of sharing the error path.&lt;/p></description></item></channel></rss>