{"id":8410,"date":"2017-04-10T19:42:42","date_gmt":"2017-04-10T16:42:42","guid":{"rendered":"http:\/\/railsware.com\/blog\/?p=8410"},"modified":"2020-11-23T14:30:10","modified_gmt":"2020-11-23T11:30:10","slug":"managing-state-of-business-logic-in-angular","status":"publish","type":"post","link":"https:\/\/railsware.com\/blog\/managing-state-of-business-logic-in-angular\/","title":{"rendered":"Managing state of business logic in Angular"},"content":{"rendered":"<p class=intro-text>I assume you\u2019ve heard a lot about state in the context of react, flux, redux. However, state appears to be a good container to represent business logic. It is much easier to maintain component when you have overview of its state. React philosophy is built on the state and it is hugely advertised. Thus it is like with Ruby on Rails, you are jumping on the train which goes into the right direction.\n<\/p>\n\n<p>Angular, on the other hand, does not restrict you to how you should manage state. There is no such advertisement or requirement to set state. There are Input params variables and famous changes detection. But what is the state? Essentially state is a number of variables which describe current context. While component behaves in a certain way depending on it\u2019s state.\n<\/p>\n\n<p>Apparently, having state variables in one place is very good for improved maintainability as well as the understanding of component dependencies and responsibilities. Let\u2019s have a look at how we can keep state in one place and share it with the ones who depend on it.<\/p>\n\n<h2>Solution<\/h2>\n\n<p>While there are a couple of redux inspired implementations out there, I would like to think in terms of angular core approaches, Dependency Injection in particular.<\/p>\n\n<p><a href=\"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/03\/MBP.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/03\/MBP-1024x399.png\" alt=\"Angular business logic\" width=\"1024\" height=\"399\" class=\"alignnone size-large wp-image-8529\" srcset=\"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/03\/MBP-1024x399.png 1024w, https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/03\/MBP-300x117.png 300w, https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/03\/MBP-768x299.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n\n<p>The idea is to keep state in the service which then can be used by multiple components to read or update state. Realisation might not be that obvious for newcomers, but it is based on basic concept of DI in angular. Service instantiated in parent component and used in child components. Let\u2019s take a look at simple example: We have a component called ParentComponent, which injects our StateService. ParentComponent holds two child components ChildOneComponent and ChildeTwoComponent. Each of these components increments counter on initialisation and shows value of the count. Expected result is that \u201c3\u201d shown at any place where we get count from the stateService.<\/p>\n\n<p>Here is the code for this example:<\/p>\n\n<pre class=\"lang:typescript\">\n\/* parent-component.ts *\/\nimport { Component, OnInit } from '@angular\/core';\nimport { StateService } from '..\/state.service';\n\n@Component({\n  selector: 'app-parent',\n  providers: [StateService],\n  template: `<p>\n               parent works! {{getCount()}}\n               <app-child-one><\/app-child-one>\n               <app-child-two><\/app-child-two>\n             <\/p>`\n})\nexport class ParentComponent implements OnInit {\n\n  constructor(private stateService: StateService) { }\n\n  ngOnInit() {\n    this.stateService.increment();\n  }\n\n  getCount() {\n    return this.stateService.getCount();\n  }\n}\n\n\/* child-one-component.ts *\/ \nimport { Component, OnInit } from '@angular\/core';\nimport { StateService } from '..\/state.service';\n\n@Component({\n  selector: 'app-child-one',\n  template: '<p>child-one works! {{getCount()}}<\/p>'\n})\nexport class ChildOneComponent implements OnInit {\n\n  constructor(private stateService: StateService) { }\n\n  ngOnInit() {\n    this.stateService.increment();\n  }\n\n  getCount() {\n    return this.stateService.getCount();\n  }\n}\n\n\/* child-two-component.ts *\/\nimport { Component, OnInit } from '@angular\/core';\nimport { StateService } from '..\/state.service';\n\n@Component({\n  selector: 'app-child-two',\n  template: '<p>child-two works! {{getCount()}}<\/p>'\n})\nexport class ChildTwoComponent implements OnInit {\n\n  constructor(private stateService: StateService) { }\n\n  ngOnInit() {\n    this.stateService.increment();\n  }\n\n  getCount() {\n    return this.stateService.getCount();\n  }\n}\n\n\/* state-service.ts *\/\nimport { Injectable } from '@angular\/core';\n\n@Injectable()\nexport class StateService {\n  count = 0;\n  constructor() { }\n\n  increment() {\n    this.count++;\n  }\n\n  getCount() {\n    return this.count;\n  }\n}\n\n\/* render of parent component *\/\n\nparent works! 3\nchild-one works! 3\nchild-two works! 3\n<\/pre>\n\n<p><strong><\/p>\n\n<h2>Conclusion<\/h2>\n\n<p><\/strong><\/p>\n\n<p>Such approach allowed me to split my big component into smaller components while giving them access to all the necessary data.<\/p>\n\n<p>\nLet me know if this is helpful to you guys. Also I\u2019m interested in how you organise complex business logic in your angular projects.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I assume you\u2019ve heard a lot about state in the context of react, flux, redux. However, state appears to be a good container to represent business logic. It is much easier to maintain component when you have overview of its state. React philosophy is built on the state and it is hugely advertised. Thus it&#8230;<\/p>\n","protected":false},"author":27,"featured_media":9415,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[],"coauthors":["Alex Mishyn"],"class_list":["post-8410","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"aioseo_notices":[],"categories_data":[{"name":"Engineering","link":"https:\/\/railsware.com\/blog?category=development"}],"post_thumbnails":"https:\/\/railsware.com\/blog\/wp-content\/uploads\/2017\/03\/MBP-1024x399.png","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts\/8410","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/comments?post=8410"}],"version-history":[{"count":21,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts\/8410\/revisions"}],"predecessor-version":[{"id":13516,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/posts\/8410\/revisions\/13516"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/media\/9415"}],"wp:attachment":[{"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/media?parent=8410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/categories?post=8410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/tags?post=8410"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/railsware.com\/blog\/wp-json\/wp\/v2\/coauthors?post=8410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}