Reputation: 308
There are different methods to get data from server in Angular application:
Both of this methods work for me but I can't understand which should I use.
First method. Get Observable from the service and subscribe to it at component:
article.service.ts
import { Injectable } from '@angular/core';
import { Article } from '../models/article';
import { AngularFirestore } from '@angular/fire/firestore';
import { map, take } from 'rxjs/operators';
import { Observable, Subject } from 'rxjs';
@Injectable({
providedIn: "root"
})
export class ArticleService {
public articlesChanged: Subject<Article[]> = new Subject<Article[]>();
articles: Article[];
constructor(private db: AngularFirestore) {}
get() {
return this.db.collection('articles').valueChanges({ idField: 'id' });
}
}
home.component.ts
import { Component, OnInit } from '@angular/core';
import { ArticleService } from 'src/app/services/article.service';
import { Observable, Subscription } from 'rxjs';
import { Article } from 'src/app/models/article';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
articles: Article[];
constructor(private articlesService: ArticleService) { }
ngOnInit() {
this.articlesService.get().subscribe(articles => this.articles = articles as Article[]);
}
}
Second method. Create Subject at the service and subscribe to the Subject at component:
article.service.ts
import { Injectable } from '@angular/core';
import { Article } from '../models/article';
import { AngularFirestore } from '@angular/fire/firestore';
import { map, take } from 'rxjs/operators';
import { Observable, Subject } from 'rxjs';
@Injectable({
providedIn: "root"
})
export class ArticleService {
public articlesChanged: Subject<Article[]> = new Subject<Article[]>();
articles: Article[];
constructor(private db: AngularFirestore) {}
get(): void {
this.db
.collection('articles')
.valueChanges({ idField: 'id' }).subscribe(articles => {
this.articles = articles as Article[];
this.articlesChanged.next(this.articles);
});
}
}
home.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ArticleService } from 'src/app/services/article.service';
import { Observable, Subscription } from 'rxjs';
import { Article } from 'src/app/models/article';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit, OnDestroy {
articlesSubscription: Subscription;
articles: Article[];
constructor(private articlesService: ArticleService) { }
ngOnInit() {
this.articlesSubscription = this.articlesService.articlesChanged.subscribe(articles => this.articles = articles);
this.articlesService.get();
}
ngOnDestroy(): void {
this.articlesSubscription.unsubscribe();
}
}
Is there a best practice which I should use?
Upvotes: 4
Views: 17916
Reputation: 3576
We can say that Subject is a special type of Observable.
Observable: Subscribe to it to get the values.
Subject: Same but you also have control of the values that you want to emit into it (can subscribe to it but also emit) you'll get the default value.
In order to understand the difference between a Subject and an Observable, you need to be aware of two distinct concepts
An observable, by definition is a data producer. That is, a special kind that can produce data over time.
A Subject on the other hand can act as both the – data producer and data consumer.
This implies two things.
That being said, there is one major difference between a subject and an observable.
All subscribers to a subject share the same execution of the subject. i.e. when a subject produces data, all of its subscribers will receive the same data. This behavior is different from observables, where each subscription causes an independent execution of the observable.
Upvotes: 10
Reputation: 2672
In your case, it may not make much difference.
However, I can see that using subject is leading to extra processing where you first get the data via valueChanges
subscription and then push it into a subject then extract data from the subject. This looks unnecessary.
However, think of another component that needs the same data that you get from db valueChanges
subscription. In such scenarios you first collect the data from the source, push it into the subject and then multiple components which have subscribed to the same subject, they all get the data.
Each component can then independently process the data and do their stuff.
As an example let's say one component triggers some change. As a result of that some processing happens (say on the backend) and data comes back to the service which houses a subject. Data is now pushed to the subject and since multiple components subscribe to this subject, they all get the same data.
As you can see this is very helpful in components communicating with each other in a loosely coupled way. You can create a loosely coupled, flexible, scalable system using this approach.
Upvotes: 1