{"id":30238,"date":"2025-05-21T16:00:52","date_gmt":"2025-05-21T14:00:52","guid":{"rendered":"https:\/\/www.angulararchitects.io\/blog\/the-new-event-api-in-ngrx-signal-store\/"},"modified":"2025-05-21T16:08:52","modified_gmt":"2025-05-21T14:08:52","slug":"the-new-event-api-in-ngrx-signal-store","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/","title":{"rendered":"The new Event API in NgRx Signal Store"},"content":{"rendered":"<p>NgRX SignalStore has released an experimental feature called NgRx SignalStore Events, marking a significant extension to the @ngrx\/signals ecosystem. This lightweight state management solution, powered by signals, has already simplified state updates. Now, it brings the familiar flux-inspired redux pattern to the ecosystem with reduced boilerplate<\/p>\n<p>As highlighted in Marko Stanimirovi\u0107's blog post <a href=\"https:\/\/dev.to\/ngrx\/announcing-events-plugin-for-ngrx-signalstore-a-modern-take-on-flux-architecture-4dhn\"><a href=\"https:\/\/dev.to\/ngrx\/announcing-events-plugin-for-ngrx-signalstore-a-modern-take-on-flux-architecture-4dhn\">https:\/\/dev.to\/ngrx\/announcing-events-plugin-for-ngrx-signalstore-a-modern-take-on-flux-architecture-4dhn<\/a><\/a>, this experimental release deserves attention and practical exploration.<\/p>\n<h2>Understanding Benefits of Events<\/h2>\n<p>Events are a powerful mechanism that can transform your Angular application into a leaner and cleaner system. What benefits can we gain?<\/p>\n<ul>\n<li>Decoupling: Producers of events simply announce &quot;something happened,&quot; and consumers can react to it.<\/li>\n<li>Flexibility: EDA allows us to add new features or modify existing ones by simply introducing new events.<\/li>\n<li>Separation of concerns: With the usage of effects, we clearly separate side effects from core logic, which helps make our codebase easier to understand, debug, and maintain.<\/li>\n<\/ul>\n<p>We could already implement some \u201ckind\u201d CQRS (Command Query Responsibility Segregation) with SignalStore in our workshops. Our methods act as commands without return values (though &quot;without&quot; might be more precise than &quot;any&quot; here \ud83d\ude09). When we send a command, it triggers our marble run\u2014behind the scenes, we query the database and transform data. Eventually, we receive the results as an updated state that we track in our frontend, though sometimes we might not receive any update at all.<\/p>\n<p>This picture illustrates the concept, simplified for a component and a store.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/CleanShot_2025-05-21_at_09.58.41.png\" alt=\"CleanShot 2025-05-21 at 09.58.41.png\" \/><\/p>\n<p>So why are we excited? First, we can now work with events that represent either commands or events in our system. For example, an event named &quot;loadSettings&quot; acts as a command\u2014we expect someone to pick it up and load these settings. Another example is &quot;loadSettingsFailed,&quot; which is an event indicating something happened within the system.<\/p>\n<p>Furthermore, we can send messages between stores and capture events within any injection context:<\/p>\n<pre><code class=\"language-tsx\"> readonly #events = inject(Events);\n constructor() {\n      this.#events\n        .on(\/* The event we want *\/)\n        .pipe(takeUntilDestroyed())\n        .subscribe(() =&gt; \/* Process *\/ );\n }<\/code><\/pre>\n<p>Currently, events are not buffered or replayed\u2014the current implementation uses an RxJS Subject, so when you lose an event due to timing issues, it's gone.<\/p>\n<p>With these possibilities, I can envision potential migration scenarios from @ngrx\/store to the new signal store.<\/p>\n<p>A possible approach would be to use the signal store with the flux\/redux pattern while leaving existing stores untouched, since there's no need to refactor well-documented and tested code solely for new technology. When you need to enhance an existing store, you can evaluate whether upgrading it to the signal store makes sense. To enable interaction between the stores, we can dispatch a global action and translate between the event systems.<\/p>\n<p>But enough with theory let\u2019s look into an example.<\/p>\n<h2>Practical Implementation: Settings Store<\/h2>\n<p>To demonstrate the practical value, let's examine a settings store implementation that manages application-wide settings. First we define our application state we want to manage:<\/p>\n<pre><code class=\"language-tsx\">export interface SettingsState {\n  theme: &quot;light&quot; | &quot;dark&quot; | &quot;system&quot;;\n  notifications: boolean;\n  language: string;\n  lastUpdated: string | null;\n  errorMessage: string | null;\n}\n\nexport const initialState: SettingsState = {\n  theme: &quot;light&quot;,\n  notifications: false,\n  language: &quot;en&quot;,\n  lastUpdated: null,\n  errorMessage: null,\n};<\/code><\/pre>\n<p>Note: In a hexagonal architecture, we would separate our core settings model from our state. However, to keep this example as simple as possible, we're using a lean approach.<\/p>\n<h2>Event Groups: Organising Application Logic<\/h2>\n<p>Let's discuss the Dispatcher service, which references both EventsService and ReducerEventsService (these derive from BaseEvents and share identical implementations). When called, the dispatch function broadcasts events simultaneously through both channels. The ReducerEvents service works specifically with the withReducer feature.<\/p>\n<p>Now, let's define our events.<\/p>\n<p>The implementation features two strategic event groups:<\/p>\n<ol>\n<li>UI Events: Handle user interactions through settingsEvents<\/li>\n<li>API Events: Manage backend communication through settingsApiEvents<\/li>\n<\/ol>\n<pre><code class=\"language-tsx\">export const settingsEvents = eventGroup({\n  source: &quot;Settings&quot;,\n  events: {\n    themeChanged: type&lt;{ theme: &quot;light&quot; | &quot;dark&quot; | &quot;system&quot; }&gt;(),\n    notificationsChanged: type&lt;{ notificationsEnabled: boolean }&gt;(),\n    languageChanged: type&lt;{ language: string }&gt;(),\n    loadSettings: type&lt;void&gt;(),\n    saveSettings: type&lt;void&gt;(),\n  },\n});\n\nexport const settingsApiEvents = eventGroup({\n  source: &quot;SettingsApi&quot;,\n  events: {\n    settingsLoadFailed: type&lt;{ error: string }&gt;(),\n    settingsSaved: type&lt;{ settings: Omit&lt;SettingsState, &quot;errorMessage&quot;&gt; }&gt;(),\n    settingsLoaded: type&lt;{ settings: Omit&lt;SettingsState, &quot;errorMessage&quot;&gt; }&gt;(),\n  },\n});<\/code><\/pre>\n<p>The API is clear and concise. I have defined two event groups: The first one, &quot;settingsEvents,&quot; combines UI events that occur when users interact with the interface\u2014like changing the theme, clicking save, or triggering a load event when entering the dialog.<\/p>\n<p>The second event group defines API events. For example, when a loadSettings event is captured by a side effect, it may request settings from the backend. This could be a long-running task that might succeed or fail. When we receive a response, we create an API event to notify our state management that the data is ready for processing.<\/p>\n<h2>Technical Deep Dive<\/h2>\n<p>The SettingsStore implementation showcases the power of custom signalStoreFeatures, ensuring clean code organization and future extensibility.<\/p>\n<pre><code class=\"language-tsx\">export const SettingsStore = signalStore(\n  withState&lt;SettingsState&gt;(initialState),\n  withSettingsReducer(),\n  withThemeFeature(),\n  withSettingsPersistenceFeature(),\n  withHooks({\n    onInit: () =&gt; {\n      const dispatch = injectDispatch(settingsEvents);\n      dispatch.loadSettings();\n    },\n  })\n);<\/code><\/pre>\n<p>We utilize custom signalStoreFeatures to improve separation of concerns and demonstrate how we can extend our store with events in the future without creating a tangled mess of spaghetti code.<\/p>\n<p>The withSettingsReducer feature, as its name suggests, is responsible for combining the previous state with an event to produce a new state. <\/p>\n<pre><code class=\"language-tsx\">export function withSettingsReducer() {\n  return signalStoreFeature(\n    withReducer(\n      on(settingsEvents.themeChanged, ({ payload }) =&gt; ({\n        theme: payload.theme,\n      })),\n      on(settingsEvents.notificationsChanged, ({ payload }) =&gt; ({\n        notifications: payload.notificationsEnabled,\n      })),\n      on(settingsEvents.languageChanged, ({ payload }) =&gt; ({\n        language: payload.language,\n      })),\n      on(settingsApiEvents.settingsSaved, () =&gt; ({\n        lastUpdated: new Date().toISOString(),\n      })),\n      on(settingsApiEvents.settingsLoadFailed, ({ payload }) =&gt; ({\n        errorMessage: payload.error,\n      })),\n      on(settingsApiEvents.settingsLoaded, ({ payload }) =&gt; payload.settings)\n    )\n  );\n}<\/code><\/pre>\n<p>The withReducer and on functions from the @ngrx\/signals\/events namespace enable listening to events and updating state with partial state updaters. As you can see from the signal store's design, we've optimized state immutability without needing to create shallow copies through object spread operators.<\/p>\n<p>Now lets look into the withThemeFeature which should give you an example how to use an effect to update for example the dom to set the current theme.<\/p>\n<pre><code class=\"language-tsx\">export function withThemeFeature() {\n  return signalStoreFeature(\n    withEffects(\n      (store, events = inject(Events)) =&gt; ({\n        loadTheme$: events.on(\n          settingsApiEvents.settingsSaved,\n          settingsApiEvents.settingsLoaded).pipe(\n          tap(({ payload }) =&gt; document.documentElement.setAttribute(\n                                                          &#039;data-theme&#039;, \n                                                                    payload.settings.theme))\n        ),\n      })\n    )\n  )\n}<\/code><\/pre>\n<p>Here we listing to both events when the settings are loaded or when they are saved to update the dom.<\/p>\n<p>Finally let\u2019s look into the component usage:<\/p>\n<pre><code class=\"language-tsx\">export class SettingsComponent {\n  protected readonly store = inject(SettingsStore);\n  protected readonly dispatch = injectDispatch(settingsEvents);\n\n  onThemeChange(theme: &#039;light&#039; | &#039;dark&#039; | &#039;system&#039;) {\n    this.dispatch.themeChanged({ theme });\n  }\n\n  onNotificationsChange(notifications: boolean) {\n    this.dispatch.notificationsChanged({ notificationsEnabled: notifications });\n  }\n\n  onLanguageChange(language: string) {\n    this.dispatch.languageChanged({ language });\n  }\n\n  onSave() {\n    this.dispatch.saveSettings();\n  }\n}<\/code><\/pre>\n<p>As Marko described in his article, injectDispatch provides us with an elegant API. Instead of using a generic dispatch function to construct events, we get a fluent API that's automatically generated from our event settings, as demonstrated above.<\/p>\n<p>The whole project is here <a href=\"https:\/\/stackblitz.com\/~\/github.com\/wolfmanfx\/signal-events\"><a href=\"https:\/\/stackblitz.com\/~\/github.com\/wolfmanfx\/signal-events\">https:\/\/stackblitz.com\/~\/github.com\/wolfmanfx\/signal-events<\/a><\/a><\/p>\n<h2>MetaReducer<\/h2>\n<p>One feature I had missed was the meta reducer. With such a meta reducer, I can implement global undo\/redo functionality or connect to the dev tools using our ngrx-toolkit.<\/p>\n<pre><code class=\"language-tsx\">export type StoreType&lt;T&gt; = {\n    [K in keyof T]: Signal&lt;T[K]&gt;;\n}\n\nexport function withMetaReducer&lt;T&gt;(metaReducer: (ev: EventInstance&lt;string, unknown&gt;, store: T) =&gt; void) {\n  return signalStoreFeature(\n    withMethods((store) =&gt; ({\n      metaReducer: rxMethod&lt;EventInstance&lt;string, unknown&gt;&gt;((c$) =&gt;\n        c$.pipe(\n          tap((ev) =&gt; {\n            metaReducer(ev, store as T);\n          })\n        )\n      ),\n    })),\n    withHooks({\n      onInit: ({ metaReducer }) =&gt; {\n        metaReducer(inject(Events).on());\n      },\n    })\n  );\n}<\/code><\/pre>\n<p>The usage is straightforward\u2014in this example, I am simply logging the events to the console.<\/p>\n<pre><code class=\"language-tsx\">  withMetaReducer&lt;StoreType&lt;SettingsState&gt;&gt;((*ev*, *store*) =&gt; {    \n      console.log(<code>MetaReducer: ${*ev*.type}<\/code>);    \n      console.log(*store*.theme());  \n    })<\/code><\/pre>\n<h2>Looking Forward<\/h2>\n<p>Here is my biased opinion regarding the Redux pattern itself. During code reviews, I've found that many companies struggle to deliver clean applications using @ngrx\/store. Developers often have difficulty understanding the code workflow because a single event can trigger multiple events (fan-out), causing applications to grow organically without clear direction. However, some companies have delivered excellent applications using Redux. So if you're one of these successful companies and want to shift to more lightweight stores while maintaining your current pattern and interactions, the NgRx team has provided a path forward with events.<\/p>\n<p>Nevertheless, this is excellent work and a great project. I'm looking forward to the next update.<\/p>\n<h2>More on this: Workshops and Reviews<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.angulararchitects.io\/en\/training\/advanced-angular-architecture-workshop\/\">Advanced Angular \u2013 Architecture Workshop<\/a><\/li>\n<li><a href=\"https:\/\/www.angulararchitects.io\/en\/training\/reaktive-angular-architekturen-mit-rxjs-und-ngrx-redux\/\">Reactive Angular Architectures with Signals and the Resource API<\/a><\/li>\n<li><a href=\"https:\/\/www.angulararchitects.io\/en\/training\/professional-ngrx-advanced-state-management-best-practices\/\">Professional NgRx Signal Store: State Patterns &amp; Best Practices<\/a><\/li>\n<li><a href=\"https:\/\/www.angulararchitects.io\/en\/contact\/\">Request Consulting, Reviews, In-House trainings<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>NgRX SignalStore has released an experimental feature called NgRx SignalStore Events, marking a significant extension to the @ngrx\/signals ecosystem. This lightweight state management solution, powered by signals, has already simplified state updates. Now, it brings the familiar flux-inspired redux pattern to the ecosystem with reduced boilerplate As highlighted in Marko Stanimirovi\u0107&#8217;s blog post https:\/\/dev.to\/ngrx\/announcing-events-plugin-for-ngrx-signalstore-a-modern-take-on-flux-architecture-4dhn, this [&hellip;]<\/p>\n","protected":false},"author":20,"featured_media":30240,"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-30238","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The new Event API in NgRx Signal Store - 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\/the-new-event-api-in-ngrx-signal-store\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The new Event API in NgRx Signal Store - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"NgRX SignalStore has released an experimental feature called NgRx SignalStore Events, marking a significant extension to the @ngrx\/signals ecosystem. This lightweight state management solution, powered by signals, has already simplified state updates. Now, it brings the familiar flux-inspired redux pattern to the ecosystem with reduced boilerplate As highlighted in Marko Stanimirovi\u0107&#039;s blog post https:\/\/dev.to\/ngrx\/announcing-events-plugin-for-ngrx-signalstore-a-modern-take-on-flux-architecture-4dhn, this [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2025-05-21T14:00:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-05-21T14:08:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/The-New-Event-API-in-NgRx-Signal-Store.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Murat Sari\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/The-New-Event-API-in-NgRx-Signal-Store.png\" \/>\n<meta name=\"twitter:creator\" content=\"@daniel\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Murat Sari\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 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\/the-new-event-api-in-ngrx-signal-store\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/\"},\"author\":{\"name\":\"Murat Sari\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/8b851c1c2595cabe82a9ce8fb10fde7c\"},\"headline\":\"The new Event API in NgRx Signal Store\",\"datePublished\":\"2025-05-21T14:00:52+00:00\",\"dateModified\":\"2025-05-21T14:08:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/\"},\"wordCount\":1112,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/bg.jpeg\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/\",\"name\":\"The new Event API in NgRx Signal Store - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/bg.jpeg\",\"datePublished\":\"2025-05-21T14:00:52+00:00\",\"dateModified\":\"2025-05-21T14:08:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/bg.jpeg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/bg.jpeg\",\"width\":2000,\"height\":1138,\"caption\":\"city with dominoes, gravity, and pattern recognition, collaborative domino-building activities, children's imaginations as craft miniature cities using dominoes, fostering creativity\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The new Event API in NgRx Signal Store\"}]},{\"@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\/8b851c1c2595cabe82a9ce8fb10fde7c\",\"name\":\"Murat Sari\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e885be3561c9cc577af106107ea6fbf4cb40dab2e6f73f715c56f07026588a35?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e885be3561c9cc577af106107ea6fbf4cb40dab2e6f73f715c56f07026588a35?s=96&d=mm&r=g\",\"caption\":\"Murat Sari\"},\"sameAs\":[\"https:\/\/x.com\/daniel\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The new Event API in NgRx Signal Store - 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\/the-new-event-api-in-ngrx-signal-store\/","og_locale":"en_US","og_type":"article","og_title":"The new Event API in NgRx Signal Store - ANGULARarchitects","og_description":"NgRX SignalStore has released an experimental feature called NgRx SignalStore Events, marking a significant extension to the @ngrx\/signals ecosystem. This lightweight state management solution, powered by signals, has already simplified state updates. Now, it brings the familiar flux-inspired redux pattern to the ecosystem with reduced boilerplate As highlighted in Marko Stanimirovi\u0107's blog post https:\/\/dev.to\/ngrx\/announcing-events-plugin-for-ngrx-signalstore-a-modern-take-on-flux-architecture-4dhn, this [&hellip;]","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/","og_site_name":"ANGULARarchitects","article_published_time":"2025-05-21T14:00:52+00:00","article_modified_time":"2025-05-21T14:08:52+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/The-New-Event-API-in-NgRx-Signal-Store.png","type":"image\/png"}],"author":"Murat Sari","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/The-New-Event-API-in-NgRx-Signal-Store.png","twitter_creator":"@daniel","twitter_misc":{"Written by":"Murat Sari","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/"},"author":{"name":"Murat Sari","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/8b851c1c2595cabe82a9ce8fb10fde7c"},"headline":"The new Event API in NgRx Signal Store","datePublished":"2025-05-21T14:00:52+00:00","dateModified":"2025-05-21T14:08:52+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/"},"wordCount":1112,"commentCount":0,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/bg.jpeg","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/","name":"The new Event API in NgRx Signal Store - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/bg.jpeg","datePublished":"2025-05-21T14:00:52+00:00","dateModified":"2025-05-21T14:08:52+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/bg.jpeg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/05\/bg.jpeg","width":2000,"height":1138,"caption":"city with dominoes, gravity, and pattern recognition, collaborative domino-building activities, children's imaginations as craft miniature cities using dominoes, fostering creativity"},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/the-new-event-api-in-ngrx-signal-store\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"The new Event API in NgRx Signal Store"}]},{"@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\/8b851c1c2595cabe82a9ce8fb10fde7c","name":"Murat Sari","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e885be3561c9cc577af106107ea6fbf4cb40dab2e6f73f715c56f07026588a35?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e885be3561c9cc577af106107ea6fbf4cb40dab2e6f73f715c56f07026588a35?s=96&d=mm&r=g","caption":"Murat Sari"},"sameAs":["https:\/\/x.com\/daniel"]}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/30238","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\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=30238"}],"version-history":[{"count":1,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/30238\/revisions"}],"predecessor-version":[{"id":30241,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/30238\/revisions\/30241"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/30240"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=30238"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=30238"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=30238"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}