{"id":25344,"date":"2024-04-03T21:21:16","date_gmt":"2024-04-03T19:21:16","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=25344"},"modified":"2025-06-04T16:57:11","modified_gmt":"2025-06-04T14:57:11","slug":"successful-with-signals-in-angular-3-effective-rules-for-your-architecture","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/","title":{"rendered":"Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture"},"content":{"rendered":"<div class=\"wp-post-series-box series-signals wp-post-series-box--expandable\">\n\t\t\t<input id=\"collapsible-series-signals6a145718ac9f4\" class=\"wp-post-series-box__toggle_checkbox\" type=\"checkbox\">\n\t\n\t<label\n\t\tclass=\"wp-post-series-box__label\"\n\t\t\t\t\tfor=\"collapsible-series-signals6a145718ac9f4\"\n\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\t\t<p class=\"wp-post-series-box__name wp-post-series-name\">\n\t\t\tThis is post 3 of 9 in the series <em>&ldquo;Signals&rdquo;<\/em>\t\t<\/p>\n\t\t\t<\/label>\n\n\t\t\t<div class=\"wp-post-series-box__posts\">\n\t\t\t<ol>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-signals\/\">Signals in Angular: Building Blocks<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/component-communication-with-signals-inputs-two-way-bindings-and-content-view-queries\/\">Component Communication with Signals: Inputs, Two-Way Bindings, and Content\/ View Queries<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><span class=\"wp-post-series-box__current\">Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture<\/span><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/skillfully-using-signals-in-angular-selected-hints-for-professional-use\/\">Skillfully Using Signals in Angular &#8211; Selected Hints for Professional Use<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/when-not-to-use-effects-in-angular-and-what-to-do-instead\/\">When (Not) to use Effects in Angular &#8212; and what to do instead<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/asynchronous-resources-with-angulars-new-resource-api\/\">Asynchronous Data Flow with Angular&#8217;s new Resource API<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/streaming-resources-in-angular-19-2-details-and-semantics\/\">Streaming Resources in Angular &#8211; Details and Semantics<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/streaming-resources-for-a-chat-with-web-sockets-messages-in-a-glitch-free-world\/\">Streaming Resources for a Chat with Web Sockets: Messages in a Glitch-Free World<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/\">Angular&#8217;s new httpResource<\/a><\/li>\n\t\t\t\t\t\t\t<\/ol>\n\t\t<\/div>\n\t<\/div>\n<p>It is undisputed that Signals will shape the future of Angular. At first glance, they seem very easy to use: The setters take new values, the getters deliver the current values and the templates as well as Effects are notified about changes.<\/p>\n<p>Now you might be tempted to treat Signals like normal variables. This works in principle and can be a practical option when migrating existing code. However, in this case, the advantages of Signals and reactive systems only result to a limited extent. There are also some pitfalls and the code is not as straightforward and hence not as maintainable as it could be.<\/p>\n<p>In order to prevent such situations, I would like to use this article to give you three simple rules of thumb that allow Signals to be used as idiomatically as possible. <\/p>\n<p>\ud83d\udcc1 <a href=\"https:\/\/github.com\/manfredsteyer\/desserts.git\">Source Code<\/a> (see different branches!)<\/p>\n<blockquote><p>\nBig thanks to Angular's <a href=\"https:\/\/twitter.com\/synalx\">Alex Rickabaugh<\/a> for a great discussion that led to the idea for this article and for providing feedback.\n<\/p><\/blockquote>\n<h2>Initial Example With Some Room for Improvement<\/h2>\n<p>I would like to discuss the three promised rules using a simple Angular application:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/dessert-app.png\" alt=\"Example application\" \/><\/p>\n<p>The first implementation considered is not reactive and also offers some room for improvement:<\/p>\n<pre><code class=\"language-typescript\">@Component([\u2026])\nexport class DessertsComponent implements OnInit {\n  #dessertService = inject(DessertService);\n  #ratingService = inject(RatingService);\n  [\u2026]\n\n  originalName = &#039;&#039;;\n  englishName = &#039;&#039;;\n  loading = false;\n\n  desserts: Dessert[] = [];\n\n  ngOnInit(): void {\n    this.search();\n  }\n\n  search(): void {\n    const filter: DessertFilter = {\n      originalName: this.originalName,\n      englishName: this.englishName,\n    };\n\n    this.loading = true;\n\n    this.#dessertService.find(filter).subscribe({\n      next: (desserts) =&gt; {\n        this.desserts = desserts;\n        this.loading = false;\n      },\n      error: (error) =&gt; { [\u2026] },\n    });\n  }\n\n  toRated(desserts: Dessert[], ratings: DessertIdToRatingMap): Dessert[] {\n    return desserts.map((d) =&gt;\n      ratings[d.id] ? { ...d, rating: ratings[d.id] } : d,\n    );\n  }\n\n  loadRatings(): void {\n    this.loading = true;\n\n    this.#ratingService.loadExpertRatings().subscribe({\n      next: (ratings) =&gt; {\n        const rated = this.toRated(this.desserts, ratings);\n        this.desserts = rated;\n        this.loading = false;\n      },\n      error: (error) =&gt; { [\u2026] },\n    });\n  }\n  [\u2026]\n}<\/code><\/pre>\n<p>Since the properties to be bound are neither Observables nor Signals, the strategy <code>OnPush<\/code> cannot be used for improving the data binding performance. Upon closer inspection, we also notice that the <code>loadRatings<\/code> method updates the <code>desserts<\/code> array, even though its actual task -- loading ratings -- has nothing to do with it.<\/p>\n<p>Additionally, developers must remember that after any changes to the ratings, the <code>desserts<\/code> array must also be modified. This is exactly what can lead to hard-to-maintain code and hidden bugs -- especially when both <code>desserts<\/code> and <code>ratings<\/code> change at different points. Things become even more complex when additional data structures have to be taken into account in these calculations. The first rule of thumb presented here solves this issue.<\/p>\n<h2>Rule 1: Derive State Synchronously Whereever Possible<\/h2>\n<p>The previously mentioned disadvantages can be compensated for with Signals. Since the introduction of Signals makes the component reactive, <code>OnPush<\/code> can now be activated. In addition, the component can derive its state from the individual Signals using <code>computed<\/code> synchronously:<\/p>\n<pre><code class=\"language-typescript\">@Component({\n  [\u2026],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class DessertsComponent implements OnInit {\n  #dessertService = inject(DessertService);\n  #ratingService = inject(RatingService);\n\n  originalName = signal(&#039;&#039;);\n  englishName = signal(&#039;&#039;);\n  loading = signal(false);\n\n  desserts = signal&lt;Dessert[]&gt;([]);\n  ratings = signal&lt;DessertIdToRatingMap&gt;({});\n  ratedDesserts = computed(() =&gt; this.toRated(this.desserts(), this.ratings()));\n\n  [\u2026]\n\n  loadRatings(): void {\n    this.loading.set(true);\n\n    this.#ratingService.loadExpertRatings().subscribe({\n      next: (ratings) =&gt; {\n        this.ratings.set(ratings);\n        this.loading.set(false);\n      },\n      error: (error) =&gt; { [\u2026] }\n  });\n\n  [\u2026]\n}<\/code><\/pre>\n<p>This makes the code a lot more straightforward: The <code>loadRatings<\/code> method simply loads the ratings and places them in a signal. The <code>computed<\/code> Signal <code>ratedDesserts<\/code> takes care of mergining <code>desserts<\/code> and <code>ratings<\/code>. No matter when and where the application updates <code>desserts<\/code> or <code>ratings<\/code>, <code>ratedDesserts<\/code> is always up to date.<\/p>\n<p>When applying this pattern, it is important to note that <code>computed<\/code> can only derive state in a synchronous manner. For an asynchronous derivation, Angular provides the <a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/asynchronous-resources-with-angulars-new-resource-api\/\">Resource API<\/a>.<\/p>\n<h2>More: Angular Architecture Workshop (online, interactive, advanced)<\/h2>\n<p>Become an expert for enterprise-scale and maintainable Angular applications with our <a href=\"https:\/\/www.angulararchitects.io\/en\/angular-workshops\/advanced-angular-enterprise-architecture-incl-ivy\/\">Angular Architecture workshop!<\/a><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2020\/06\/ent-en-1.jpg\" alt=\"\" \/><\/p>\n<p><a href=\"https:\/\/www.angulararchitects.io\/en\/angular-workshops\/advanced-angular-enterprise-architecture-incl-ivy\/\">All Details (English Workshop)<\/a> | <a href=\"https:\/\/www.angulararchitects.io\/schulungen\/advanced-angular-enterprise-anwendungen-und-architektur\/\">All Details (German Workshop)<\/a><br \/>\n<\/p>\n<h2>Rule 2: Avoid Effects for Propagating State<\/h2>\n<p>Effects are the right choice when presenting values cannot be achieved via data binding. However, they bring some pitfalls when used for propagating change. In the next sections, I elaborate on this.<\/p>\n<h3>Proper Usage of Effects<\/h3>\n<p>In most cases, Signals are bound in the template. However, it happens that the desired form of output cannot be achieved via data binding. An example of this is outputting a Signal to the console for debugging purposes. Another example are toasts that can be activated via services and are intended to present the value of a Signal. For these cases, Angular provides Effects:<\/p>\n<pre><code class=\"language-typescript\">[\u2026]\nconstructor() {\n  effect(() =&gt; {\n    console.log(&#039;originalName&#039;, this.originalName());\n    console.log(&#039;englishName&#039;, this.englishName());\n  });\n\n  effect(() =&gt; {\n    this.#toastService.show(this.desserts().length + &#039; desserts loaded!&#039;);\n  });\n}\n[\u2026]<\/code><\/pre>\n<h3>Signals are Glitch-free<\/h3>\n<p>When writing code like in the previous section, we need to be aware that Signals are glitch-free. That means that if you change a signal several times in a row (within a stack frame), only the last change will be seen by the consumer, e.g. the effect:<\/p>\n<pre><code class=\"language-typescript\">@Component([...])\nexport class AboutComponent {\n\n  constructor() {\n    const signal1 = signal(&#039;A&#039;);\n    const signal2 = signal(&#039;B&#039;);\n\n    effect(() =&gt; {\n      console.log(&#039;signal1&#039;, signal1());\n      console.log(&#039;signal2&#039;, signal2());\n    });\n\n    signal1.set(&#039;C&#039;);\n    signal1.set(&#039;D&#039;);\n\n    signal1.set(&#039;E&#039;);\n\n    signal2.set(&#039;F&#039;);\n  }\n}<\/code><\/pre>\n<p>In this case, we will only see the values <code>E<\/code> and <code>F<\/code> on the console. Indemediate values are skipped.<\/p>\n<p>This shows that Signals are not intended for modelling events but for data we want to bind to the view. In the latter case, we just need the current value while binding intermediate values would be counterproductive. For this reasons, the effects shown in the previous section are only triggered once even if there are several changes in a row. <\/p>\n<p>In cases where we want to express events, Observables are the way to go, as they don't have this glitch-free guarantee by design.<\/p>\n<h3>Problematic Use of Effects<\/h3>\n<p>Even when using Effects, Signals are primarily used to transport the desired data into the view. In theory, however, Effects could also be used to transmit state to other Signals:<\/p>\n<pre><code class=\"language-typescript\">effect(() =&gt; {\n    this.originalName.set(this.englishName());\n});<\/code><\/pre>\n<p>However, such approaches have several disadvantages, which is why Angular prohibits writing Signals within Effects by default:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/signal-write-error.png\" alt=\"Error message when trying to set a Signal in an Effect\" \/><\/p>\n<p>One of these disadvantages is that unmanageable change cascades and thus difficult-to-maintain code and cyclic dependencies can arise. Since Effects register implicitly with all Signals used, the associated problems may not even be noticeable at first glance. If you still want to use Effects for writing, you can make Angular let things slide by setting <code>allowSignalWrites<\/code>:<\/p>\n<pre><code class=\"language-typescript\">\/\/ Try hard to avoid this\neffect(() =&gt; {\n    this.originalName.set(this.englishName());\n  },\n  { allowSignalWrites: true },\n);<\/code><\/pre>\n<blockquote><p>\nApplication code should only use <code>allowSignalWrites<\/code> as a last resort.\n<\/p><\/blockquote>\n<p>The general consensus in the community is that application code should only use <code>allowSignalWrites<\/code> as a last resort. On the other hand, libraries like NGRX use this option internally. In this case, however, the authors of the library are responsible for its correct use, so application developers don't have to worry about it.<\/p>\n<p>It is also important to note that the Effect itself registers with Signals in called methods too. For instance, the following Effect is triggered when Signals change within <code>search<\/code>:<\/p>\n<pre><code class=\"language-typescript\">\/\/ Try hard to avoid this\neffect(() =&gt; {\n    this.search();\n  },\n  { allowSignalWrites: true },\n);<\/code><\/pre>\n<p>This leads to a further increase in complexity. At least this problem could be alleviated with built-in features:<\/p>\n<pre><code class=\"language-typescript\">\/\/ Try hard to avoid this\neffect(() =&gt; {\n    const originalName = this.originalName(); \n    const englishName = this.englishName();\n    untracked(() =&gt; {\n        this.load(originalName, englishName);\n    })\n  }\n);<\/code><\/pre>\n<p>The <code>untracked<\/code> function avoids the current reactive context spilling over to the called <code>search<\/code> method. Angular now also uses this pattern itself in <a href=\"https:\/\/github.com\/angular\/angular\/pull\/54614\">selected cases<\/a>. An example of this is triggering events in sub-components so that the event handler does not run in the reactive context of the code that triggered the event. Further popular libraries that use this technique are NGRX, NGRX Signal Store or ngextensions.<\/p>\n<h3>Strategies for Preventing Effects With Signal Writes<\/h3>\n<p>Effects that spread data via Signal writes can in many cases be prevented using the following approaches:<\/p>\n<ul>\n<li>Consistent derivation of state using <code>computed<\/code> (see rule 1, above) or the <a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/asynchronous-resources-with-angulars-new-resource-api\/\">Resource API<\/a><\/li>\n<li>Direct use of events that caused the Signal to change.<\/li>\n<\/ul>\n<p>Instead of calling <code>search<\/code>, as indicated above, in an Effect, the application could instead use the change event of the input fields for the search filters. Observables can also be used as a source for such actions. The <code>search<\/code> method could, for example, also be triggered by the <code>valueChanges<\/code> observable of a <code>FormGroup<\/code>. In cases where you have just Signals, they can be converted into Observables using the RxJS Interop offered by Angular:<\/p>\n<pre><code class=\"language-typescript\">@Component([\u2026])\nexport class DessertsComponent {\n  #dessertService = inject(DessertService);\n  #ratingService = inject(RatingService);\n  #toastService = inject(ToastService);\n\n  originalName = signal(&#039;&#039;);\n  englishName = signal(&#039;Cake&#039;);\n  loading = signal(false);\n\n  originalName$ = toObservable(this.originalName);\n  englishName$ = toObservable(this.englishName);\n\n  desserts$ = combineLatest({\n    originalName: this.originalName$,\n    englishName: this.englishName$,\n  }).pipe(\n    filter((c) =&gt; c.originalName.length &gt;= 3 || c.englishName.length &gt;= 3),\n    debounceTime(300),\n    tap(() =&gt; this.loading.set(true)),\n    switchMap((c) =&gt; this.findDesserts(c)),\n    tap(() =&gt; this.loading.set(false)),\n  );\n\n  desserts = toSignal(this.desserts$, {\n    initialValue: [],\n  });\n\n  ratings = signal&lt;DessertIdToRatingMap&gt;({});\n  ratedDesserts = computed(() =&gt; this.toRated(this.desserts(), this.ratings()));\n\n  findDesserts(c: DessertFilter): Observable&lt;Dessert[]&gt; {\n    return this.#dessertService.find(c).pipe(\n      catchError((error) =&gt; {\n        this.#toastService.show(&#039;Error loading desserts!&#039;);\n        console.error(error);\n        return of([]);\n      }),\n    );\n  }\n  [\u2026]\n}<\/code><\/pre>\n<blockquote><p>\nThe flattening operators offered by RxJS provide guarantees for overlapping asynchronous actions and thus prevent race conditions.\n<\/p><\/blockquote>\n<p>The use of Observables has several advantages at this point:<\/p>\n<ul>\n<li>In contrast to Signals, Observables are also suitable for triggering asynchronous actions.<\/li>\n<li><code>toObservable<\/code> function strips the current reactive context using <code>untracked<\/code>.<\/li>\n<li>RxJS comes with a lot of powerful operators, like <code>debounceTime<\/code>.<\/li>\n<li>The flattening operators offered by RxJS provide guarantees for overlapping asynchronous actions and thus prevent race conditions. In the example shown, <code>switchMap<\/code> ensures that when search queries overlap, only the result of the last one is used and all others are canceled.<\/li>\n<\/ul>\n<p>In many cases, one could argue that instead of converting a Signal into an Observable, it would be more appropriate to directly use the event that led to the Signal change, as proposed above. On the other hand, as Angular APIs increasingly adopt Signal-based approaches, using them directly will likely become more convenient and feel more intuitive. Therefore, this appears to be a gray area where we need to be mindful of the consequences, such as those associated with the glitch-free guarantee of Signals. I plan to discuss this topic in more detail in a subsequent article.<\/p>\n<h2>Rule 3: Stores Simplify Reactive Data Flow<\/h2>\n<p>Stores like the classic NGRX Store or the lightweight NGRX Signal Store not only take care of state management, but also help to keep the reactive data flow manageable:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/store.png\" alt=\"Unidirectional data flow with a store\" \/><\/p>\n<p>The application forwards its intention to the store as part of an event. At this point, I use the term intention in an abstract, technology-neutral way, especially since different stores realize this aspect differently. With Redux and therefore also when using the classic NGRX store the application sends an action to the store, which forwards it to Reducer and Effects. For lightweight stores like the NGRX Signal Store, the application delegates to a method offered by the store instead.<\/p>\n<blockquote><p>\nOffloading asynchronous operations to the store also compensates for the fact that Signals are currently only designed for synchronous actions.\n<\/p><\/blockquote>\n<p>The store then takes action and initiates synchronous or asynchronous operations. If the application uses RxJS for this, race conditions can be avoided with the flattening operators, as mentioned above. Offloading asynchronous operations to the store also compensates for the fact that Signals are currently only designed for synchronous actions.<\/p>\n<p>The result of these operations leads to a change in the state managed by the store. This state can be expressed by Signals, which can be mapped to other Signals using computing (see rule 1). Such mappings can occur both in the store and in the component (or in another consumer of the store). This depends on how local or global the store and the data to be derived are.<\/p>\n<p>The bottom line is that the consistent use of this approach supports the so-called unidirectional data flow, which makes system behavior more understandable. The following listing demonstrates this from the perspective of a component that relies on the NGRX Signal Store.<\/p>\n<pre><code class=\"language-typescript\">@Component([\u2026])\nexport class DessertsComponent {\n  #store = inject(DessertStore);\n\n  originalName = this.#store.filter.originalName;\n  englishName = this.#store.filter.englishName;\n\n  ratedDesserts = this.#store.ratedDesserts;\n  loading = this.#store.loading;\n\n  constructor() {\n    this.#store.loadDesserts();\n  }\n\n  search(): void {\n    this.#store.loadDesserts();\n  }\n\n  loadRatings(): void {\n    this.#store.loadRatings();\n  }\n\n  updateRating(id: number, rating: number): void {\n    this.#store.updateRating(id, rating);\n  }\n\n  updateFilter(filter: DessertFilter): void {\n    this.#store.updateFilter(filter);\n  }\n}<\/code><\/pre>\n<p>Since the component only has to delegate to the store, it is very straightforward.<\/p>\n<h2>Summary<\/h2>\n<p>To truly leverage the benefits of Signals, the application must be designed as a reactive system. This means, among other things, that writing values is avoided in favor of deriving values from existing ones. This simplifies the program code, especially since derived values are automatically kept up to date.<\/p>\n<p>Signals are currently primarily suitable for transporting data into the view. Effects are used when API calls are necessary for that, e.g. when displaying a toast. The current Signals implementation is not intended to trigger asynchronous actions. Instead, classic events or observables are the way to go. Stores that can also handle asynchronous operations help establish unidirectional data flow and make reactive applications more manageable.<\/p>\n<h2>What's next? More on Architecture!<\/h2>\n<p>Please find more information on enterprise-scale Angular architectures in our free eBook (5th edition, 12 chapters):<\/p>\n<ul>\n<li>According to which criteria can we subdivide a huge application into sub-domains?<\/li>\n<li>How can we make sure, the solution is maintainable for years or even decades?<\/li>\n<li>Which options from Micro Frontends are provided by Module Federation?<\/li>\n<\/ul>\n<p><a href=\"https:\/\/www.angulararchitects.io\/book\"><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/12\/cover-5th-small.png\" alt=\"free\" \/><\/a><\/p>\n<p>Feel free to <a href=\"https:\/\/www.angulararchitects.io\/en\/book\">download it here<\/a> now!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is post 3 of 9 in the series &ldquo;Signals&rdquo; Signals in Angular: Building Blocks Component Communication with Signals: Inputs, Two-Way Bindings, and Content\/ View Queries Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture Skillfully Using Signals in Angular &#8211; Selected Hints for Professional Use When (Not) to use Effects in [&hellip;]<\/p>\n","protected":false},"author":25,"featured_media":25340,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[18],"tags":[],"class_list":["post-25344","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","post_series-signals"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Successful with Signals in Angular - 3 Effective Rules for Your Architecture - ANGULARarchitects<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Successful with Signals in Angular - 3 Effective Rules for Your Architecture - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"This is post 3 of 9 in the series &ldquo;Signals&rdquo; Signals in Angular: Building Blocks Component Communication with Signals: Inputs, Two-Way Bindings, and Content\/ View Queries Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture Skillfully Using Signals in Angular &#8211; Selected Hints for Professional Use When (Not) to use Effects in [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2024-04-03T19:21:16+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-04T14:57:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/sujet.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manfred Steyer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/sujet.jpg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/\"},\"author\":{\"name\":\"Manfred Steyer\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\"},\"headline\":\"Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture\",\"datePublished\":\"2024-04-03T19:21:16+00:00\",\"dateModified\":\"2025-06-04T14:57:11+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/\"},\"wordCount\":1798,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/shutterstock_1906640938.jpg\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/\",\"name\":\"Successful with Signals in Angular - 3 Effective Rules for Your Architecture - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/shutterstock_1906640938.jpg\",\"datePublished\":\"2024-04-03T19:21:16+00:00\",\"dateModified\":\"2025-06-04T14:57:11+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/shutterstock_1906640938.jpg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/shutterstock_1906640938.jpg\",\"width\":1000,\"height\":667},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\",\"name\":\"Manfred Steyer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Successful with Signals in Angular - 3 Effective Rules for Your Architecture - ANGULARarchitects","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/","og_locale":"en_US","og_type":"article","og_title":"Successful with Signals in Angular - 3 Effective Rules for Your Architecture - ANGULARarchitects","og_description":"This is post 3 of 9 in the series &ldquo;Signals&rdquo; Signals in Angular: Building Blocks Component Communication with Signals: Inputs, Two-Way Bindings, and Content\/ View Queries Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture Skillfully Using Signals in Angular &#8211; Selected Hints for Professional Use When (Not) to use Effects in [&hellip;]","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/","og_site_name":"ANGULARarchitects","article_published_time":"2024-04-03T19:21:16+00:00","article_modified_time":"2025-06-04T14:57:11+00:00","og_image":[{"width":1280,"height":720,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/sujet.jpg","type":"image\/jpeg"}],"author":"Manfred Steyer","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/sujet.jpg","twitter_misc":{"Written by":"Manfred Steyer","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/"},"author":{"name":"Manfred Steyer","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a"},"headline":"Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture","datePublished":"2024-04-03T19:21:16+00:00","dateModified":"2025-06-04T14:57:11+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/"},"wordCount":1798,"commentCount":0,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/shutterstock_1906640938.jpg","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/","name":"Successful with Signals in Angular - 3 Effective Rules for Your Architecture - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/shutterstock_1906640938.jpg","datePublished":"2024-04-03T19:21:16+00:00","dateModified":"2025-06-04T14:57:11+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/shutterstock_1906640938.jpg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2024\/04\/shutterstock_1906640938.jpg","width":1000,"height":667},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a","name":"Manfred Steyer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","caption":"Manfred Steyer"}}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/25344","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=25344"}],"version-history":[{"count":9,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/25344\/revisions"}],"predecessor-version":[{"id":30518,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/25344\/revisions\/30518"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/25340"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=25344"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=25344"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=25344"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}