AngularJS

Understanding Smart and Dumb Components in Angular

Share

In this blog, we will see smart components and dumb components in Angular, why you should use this pattern in your app, and the execution or implementation of smart and dumb components. Angular has strong and extraordinary features because of the frequent and timely updates. To talk about Smart Components and Dumb Components, they do not have anything to do it with Angular, it is just an approach we can use in any framework or library like react, Vue, etc.

The component structure will look like the following:

We will divide our Chat component into three parts.

Dumb Component

Dumb components are the components that does not have a bunch of long-lived states. It does not have access to services nor have stored data in a back-end, all kinds of things that actually keep the focus of the component on presentation. We can also call them Isolated Components or Pure Components. Dumb or child component is only showing the data got from Smart Component.

my-chat.service.ts

import { Injectable } from ‘@angular/core’;

import { UserMessage } from ‘src/app/mychat.model’;

import { YtChannel } from ‘src/app/yt-channel.model’;

@Injectable()

export class MyChatService {

  private channelsDb: YtChannel[] = [

    { _id: ‘0’, name: ‘general’ },

    { _id: ‘1’, name: ‘channel1’ }

  ];

  // fake database

  private messagesDb: UserMessage[] = [

    { _id: ‘0’, YtchannelId: ‘0’, userId: ‘0’, userName: ‘Manoj’, content: ‘Hello!’, timestamp: new Date() },

    { _id: ‘1’, YtchannelId: ‘1’, userId: ‘0’, userName: ‘Ankit’, content: ‘Hi!’, timestamp: new Date() },

    { _id: ‘2’, YtchannelId: ‘0’, userId: ‘0’, userName: ‘Jignesh’, content: ‘Hi! Good Morning’, timestamp: new Date() }

  ];

  channels: YtChannel[] = [];

  messages: UserMessage[] = [];

  channel: YtChannel;

  getYtChannels(): void {

    // fake API, get your ytchannel data from the database

    this.channels = this.channelsDb;

    this.channel = this.channels[0];

  }

  getYourMessages(channelName: string): void {

    // fake API, get your message data from the database

    let channelId = ”;

    this.channelsDb.map(channel => {

      if (channel.name === channelName) {

        channelId = channel._id;

      }

    });

    const messages = [];

    this.messagesDb.map(message => {

      if (message.YtchannelId === channelId) {

        messages.push(message);

      }

    });

    this.messages = messages;

  }

  selectYtChannel(channel: YtChannel): void {

    this.channel = channel;

    this.getYourMessages(channel.name);

  }

  sendYourMessage(channelId: string, messageContent: string): void {

    const message = {

      _id: String(this.messagesDb.length),

      channelId,

      userId: ‘0’,

      userName: ‘Manoj’,

      content: messageContent,

      timestamp: new Date()

    };

    this.messages = […this.messages, message];

    this.messages = […this.messages, message];

    // fake API, write message data to the database

    this.messagesDb = […this.messagesDb, message];

  }

  constructor() { }

}

my-chat-area-bottom.component.ts

import { Component, EventEmitter, Input, OnInit, Output } from ‘@angular/core’;

import { FormBuilder, FormGroup, Validators } from ‘@angular/forms’;

@Component({

  selector: ‘app-my-chat-area-bottom’,

  templateUrl: ‘./my-chat-area-bottom.component.html’,

  styleUrls: [‘./my-chat-area-bottom.component.css’]

})

export class MyChatAreaBottomComponent implements OnInit {

  @Input() ytChannelId: string;

  @Output() sendYourMessage = new EventEmitter<any>();

  messageForm: FormGroup;

  constructor(

    private fb: FormBuilder

  ) { }

  ngOnInit() {

    this.messageForm = this.fb.group({

      message: [”, Validators.required]

    });

  }

  onSendMessage() {

    if (!this.messageForm.valid) return;

    this.sendYourMessage.emit({ channelId: this.ytChannelId, messageContent: this.messageForm.value.message });

    this.messageForm.reset();

  }

}

my-chat-area-bottom.component.html

<div class=”wrapper”>

    <form [formGroup]=”messageForm” (ngSubmit)=”onSendYourMessage()”>

        <input formControlName=”message” placeholder=”Click on enter to send message” />

    </form>

</div>

If you verify the above code snippet, there is nothing new excepting @input () and @output ().

 @Input() ytChannelId: string;

 @Output() sendYourMessage = new EventEmitter<any>();

ytChannelId and sendYourMessage are equivalent to the values

<my-chat-area-bottom>

    [YtChannelId]=”mychatService.ytchannel?._id”

    (sendYourMessage)=”onSendYourMessage($event)”>

</my-chat-area-bottom>

Now you need to be clear about how they equivalent to each other.

Observe that, sendYourMessage is an EventEmitter, which can help us to release the event to the parent component in our scenario, it excludes the event with an object to the parent component.

this.sendYourMessage.emit({ channelId: this.ytChannelId, messageContent: this.messageForm.value.message });

ytchannel-list-component.ts

import { Component, EventEmitter, Input, OnInit, Output } from ‘@angular/core’;

import { YtChannel } from ‘src/app/yt-channel.model’;

@Component({

  selector: ‘app-ytchannel-list’,

  templateUrl: ‘./ytchannel-list.component.html’,

  styleUrls: [‘./ytchannel-list.component.css’]

})

export class YtchannelListComponent implements OnInit {

  constructor() { }

  @Input() channels: YtChannel[];

  @Input() ytChannelId: string;

  @Output() selectYtChannel = new EventEmitter<YtChannel>();

  onSelectYtChannel(channel: YtChannel) {

    this.selectYtChannel.emit(channel);

  }

  ngOnInit(): void {

  }

}

ytchannel-list-component.html

<ul>

    <li *ngFor=”let channel of channels” [ngClass]=”{‘selected’: ytchannel._id === ytChannelId}”

        (click)=”onSelectYtChannel(channel)”>

        {{channel.name}}

    </li>

</ul>

my-chat-area-dialog-component.ts

import { Component, Input, OnInit } from ‘@angular/core’;

import { UserMessage } from ‘..//mychat.model’;

@Component({

  selector: ‘app-my-chat-area-dialog’,

  templateUrl: ‘./my-chat-area-dialog.component.html’,

  styleUrls: [‘./my-chat-area-dialog.component.css’]

})

export class MyChatAreaDialogComponent implements OnInit {

  @Input() messages: UserMessage[];

  constructor() { }

  ngOnInit(): void {

  }

}

my-chat-area-dialog-component.html

<ul class=”wrapper”>

    <li *ngFor=”let message of messages”>

        <p><span class=”name”>{{message.userName}}</span> <span

                class=”timestamp”>{{message.timestamp | calendar}}</span></p>

        <p>{{message.content}}</p>

    </li>

</ul>

Smart Component

  • Smart Components are only those components, which have states, implementing services, or any kind of business logic occurrence in that component. It does not attend on presentation but what is occurring in our component. Then we easily emit the property to Dumb Components which are obtained by @input decorator.
  • We can also call them Application-level Components or Container Components.
  • A smart or present component is responsible to communicate with the server or cloud through the Service.
  • The MyChatComponent is the first smart one or parent component

my-chat.component.ts

import { Component, OnInit } from ‘@angular/core’;

import { MyChatService } from ‘src/app/my-chat.service’;

import { YtChannel } from ‘src/app/yt-channel.model’;

@Component({

  selector: ‘app-my-chat’,

  templateUrl: ‘./my-chat.component.html’,

  styleUrls: [‘./my-chat.component.css’]

})

export class MyChatComponent implements OnInit {

  constructor(

    private mychatService: MyChatService

  ) { }

  ngOnInit() {

    this.mychatService.getYtChannels();

    this.mychatService.getYourMessages(‘general’);

  }

  onSelectYtChannel(ytchannel: YtChannel) {

    this.mychatService.selectYtChannel(ytchannel);

  }

  onSendYourMessage({ YtChannelId, messageContent }) {

    this.mychatService.sendYourMessage(YtChannelId, messageContent);

  }

}

my-chat.component.html

<div class=”left”>

    <my-channel-list [ytchannels]=”mychatService.channels” [ytchannelId]=”mychatService.ytchannel?._id”

        (selectYtChannel)=”onSelectYtChannel($event)”>

    </my-channel-list>

</div>

<div class=”right”>

    <my-chat-area-dialog [messages]=”mychatService.messages”>

    </my-chat-area-dialog>

    <my-chat-area-bottom [YtChannelId]=”mychatService.ytchannel?._id” (sendYourMessage)=”onSendYourMessage($event)”>

    </my-chat-area-bottom>

</div>

Let we use <my-chat-area-bottom> to define how smart or parent component and dumb or child component communicate:

<my-chat-area-bottom>

    [YtChannelId]=”mychatService.ytchannel?._id”

    (sendYourMessage)=”onSendYourMessage($event)”>

</my-chat-area-bottom>

Property Binding

[YtChannelId]=”mychatService.ytchannel?._id”

  • Whenever we want to transfer or communicate data from parent component to a child component, we can use Property Binding.
  • In our scenario, YtChannelId it is the property name and mychatService.ytchannel? _id is the data we want to transfer to the child component.

Event Binding

(sendYourMessage)=”onSendYourMessage($event)”

  • Whenever we want to pass or send some data from the child component to the parent component, we can use Event Binding.

Following are the benefits of using Smart Component approaches:

  • Smart Components are easily shared throughout our application if it configured correctly.
  • We can believe that these things are all heading off in isolation.
  • Have a Stable Experience.
  • They are going to help you to architect and scale your application.

Conclusion

In this blog, we have seen Angular Smart and Dumb Component Architecture in which we have defined the Smart and Dumb Component with the proper example and explanation of it. We have also seen the main benefits of using a Smart component.

Recent Posts

The Sharp-Looking Guy: 5 Essential Tips for Men to Become Sharp

We've gotten so used to seeing men streetwear joggers, ripped jeans, and sleeveless shirts. Hair…

1 day ago

How to Use Your Wedding Jewellery In Unique Ways At Festivals

When it comes to festivals, the options for wedding jewellery are endless. You can go…

1 day ago

5 Tips On Window Cleaning

Whether it concerns your home or an office building, the state of a property’s windows…

1 day ago

Sustainable Business Practices: A Win-Win Strategy

You know that running an environmentally sustainable business is the right thing to do. But…

1 day ago

Unlock Growth – Guide to Online Financing and Business Loans for Entrepreneurs

If you are in a financial crisis , or need to start a new business…

1 day ago

7 Key Factors That Help In Selecting the Best Fleet Management Software

To realize the strategic advantage from the fleet management system (FMS) and differentiate the business…

2 days ago