Search code examples
angulardesign-patternscomponentsstrategy-pattern

Similar components with different business logic in Angular


I have a question about good practice in Angular. I need to create 2 similar components with the exact same look but in different logic i.e. one of them working locally in the browser, another one, talking" with the backend.

What is the best practice in that situation?

Should I create two different components because of different logic (in files .scss and .html will be duplicated code) or maybe use something like, Strategy pattern" and try to inject different Services to the same component or something else?


Solution

  • As you mentioned, there ara so many "Angular" considered ways to implement your wish. You can pass an Input into the componenet and do different logic based on it, You can just create 2 different components, and so on.

    But, sending an addiotional Input is an ugly solution. And create 2 different components with all their files breakes the first rule of DRY - don't repeat yourself.

    So, my favorite solution for such cases is to create just one template and one style file. Then craete 2 different component classes which are pointing both to those tempalte & style. Then put in each component class the special logic for this componemt.

    In addition, in case that you have base logic that is shared between both components and just part of the logic which is separated, You can create a BaseComponent class which will include the main logic, then add 2 more classes which will inherite the base class and put in them their special logic.

    Simple example - Please note the same templateUrl & styleUrls values in components decorators:

    export class BaseComponent implements OnInit {
        constructor() {}
    
        ngOnInit(): void {}
    
        //Put here shared logic
    }
    
    
    @Component({
        selector: 'app-a',
        templateUrl: './same-template.html',
        styleUrls: ['./same-style.scss']
    })
    export class AComponent extends BaseComponent implements OnInit {
        constructor() {}
    
        ngOnInit(): void {}
    
        // Put special logic here
    }
    
    
    @Component({
        selector: 'app-b',
        templateUrl: './same-template.html',
        styleUrls: ['./same-style.scss']
    })
    export class BComponent extends BaseComponent implements OnInit {
        constructor() {}
    
        ngOnInit(): void {}
    
        // Put special logic here
    }