Introduction
In this article, we are going to learn how to achieve Separation of Concern in our component or in an application.
Prerequisites
- HTML, CSS, and JS
- Basics of TypeScript.
What do we mean by “Separation of Concern?"
Think of a school, there are different jobs. We have a teachers whose purpose is to teach, students have their own task which is to learn, guards have their own job, the principal has their own job, the library assistant has their separate job etc. Students don’t teach, the lab assistant is not working in place of the guard etc. In object oriented programming we have the same concept.
Our class should perform single operations, the class that does too many things just violates the “Separation of concern” concept and such a class is hard to maintain and hard to test. In the below example the component is involved in two different concerns. One is the presentation logic behind the view and other logic is getting the data. It needs to know the end points and it needs to know the http class. In updating and deleting the data it needs to construct the URL. These are the different concerns. In the larger application we can use the same component in different pages because this may not be the only page which is using the specified component, and if we are using the component in different places then again we need to know the URL and the required endpoints. So any changes in any logic will lead to changes in so many places.
We have a component as below,
- import { Component, OnInit } from '@angular/core';
- import { Http } from '@angular/http';
- @Component({
- selector: 'app-posts',
- templateUrl: './posts.component.html',
- styleUrls: ['./posts.component.css']
- })
- export class PostsComponent implements OnInit {
- posts: any[];
- private url = 'http://jsonplaceholder.typicode.com/posts';
- constructor(private http: Http)
- {
- http.get(this.url)
- .subscribe(response=> {
- console.log(response.json());
- this.posts = response.json();
- });
- }
- ngOnInit() {
- }
- createPost(input: HTMLInputElement)
- {
- let post = {title: input.value};
- input.value='';
- this.http.post(this.url, JSON.stringify(post))
- .subscribe(response => {
- post['id'] = response.json().id;
- this.posts.splice(0,0,post);
- console.log(response.json());
- });
- }
- updatePost(post)
- {
- this.http.patch(this.url + '/' + post.id, JSON.stringify({isRead: true}))
- .subscribe(response=> {
- console.log(response.json);
- })
- }
- deletePost(post)
- {
- this.http.delete(this.url + '/' + post.id)
- .subscribe(response=> {
- let index = this.posts.indexOf(post);
- this.posts.splice(index, 1);
- console.log(response.json);
- })
- }
- }
In our current implementation of PostComponent we have some methods like ngOnInit, createPost, DeletePost etc. There is a problem with this implementation, the problem is that it violates the “Separation of concern” principle.
Also for testing this implementation is little bit harder to test.
Let us suppose we are adding an automated test for the UpdatePost as given below.
- updatePost(post)
- {
- this.http.patch(this.url + '/' + post.id, JSON.stringify({isRead: true}))
- .subscribe(response=> {
- console.log(response.json);
- })
In our unit test we don’t want the live server running. So we want to isolate the component and only focus on the logic implementation here. In other words we don’t want http call to the server because this has two problems; the first problem is if the server is not running then our unit test will fail and the second problem is that all these http calls are going to slow down the our automated test. We want hundred or thousands of unit test to run in a few seconds, that’s why we never ever call the http server in our automated test.
Solution

Solution is to create a separate class that we call a service and this class will only be responsible for working with our backend. So if we want to get the post, create the post, delete the post we just need to delegate the responsibility to that class that we call it a service and this will solve the two issue that we discussed.
First of all all the details of working with the backend is encapsulated in one place and we can reuse this on multiple places. In the future if some detail is getting changed, suppose the url changes, we need to change in only one place.


Sani YadavPosted Apr 17, 2020, 6:26 AM
Nice and Useful article.