Why is it better to subscribe to service subject instead of getting data from function?

Issue

I have a chat messages list in my angular chat app. I get the data with messages from ChatMessagesService. In ChatViewComponent I register service in the constructor then I get the data from service and put them to component array which I use to render the messages.

Service has two functions, one to set incoming new messages from websoceket and push them to local service array, second fn to return local service (the same) array with messages.

I am during learning angular for two weeks and during this time I am making own app. I wonder, why in the component I should subscribe to observable subject from the service (as one of the course what I watching says) if just that I use function from the service which only return me array of messages, and every change in this array in the service affects to my chat view array to, without using subscribe.

ChatViewComponent

@Component({
  selector: 'conpeek-chat-view',
  template: '
<div class="row conpeek_message_chat_row" *ngFor="let chatMessage of chatMessages"> ... </div>
'
  styleUrls: ['./chat-view.component.css']
})

export class ChatViewComponent implements AfterViewInit {
  constructor(private chatMessagesService: ChatMessagesService) {
    this.chatMessages = this.chatMessagesService.getMessages();
  }
}

ChatMessagesService

export class ChatMessagesService {

  constructor(public dialogMembersService:DialogMembersService) {
  }

  chatMessages = [];

  getMessages(){
    return this.chatMessages;
  }

  addMessage(chatMessage){
    this.chatMessages.push(chatMessage);
  }
}

What is the difference between chatMessages = []; as a subject and return this as normal array if the changes are emited to all components which use this service even if it is not an observable object?

Solution

Have you heard about Angular change detection strategy ?

Default strategy will check the view every time an event is propagated in component (mouse, click, input, XHR, etc). This strategy is not adapted on complex application because performance can be terrible.

An alternative is to use OnPush strategy. This strategy will rerender the view only when @Input have changed or when you explicitly ask to detect change with ChangeDetectorRef.detectChanges();

So if you don’t want use subscription do get new datas, Angular will not be aware of your change on will not update the view.

I really suggest you to be confortable with Observable because it’s a mandatory usage.

Add subscribe() everywhere can be weary but that’s because it’s a bad practices. You should use async pipe provided by Angular.
This pipe will subscribe your datas and unsubscribe it when component will be destroyed.

The learning curve is hard but benefits are so powerful.

@Component({
  selector: 'conpeek-chat-view',
  template: '
<div class="row conpeek_message_chat_row" *ngFor="let chatMessage of chatMessages | async"> ... </div>
'
  styleUrls: ['./chat-view.component.css']
})

export class ChatViewComponent implements AfterViewInit {

  public chatMessages$: Observable<any[]>;
  constructor(private chatMessagesService: ChatMessagesService) {
    this.chatMessages$ = this.chatMessagesService.getMessages();
  }
}

Answered By – Martin Choraine

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published