Reputation: 2249
I have an Angular service in which I get data from the backend. Now inside this service, I have a variable of type ReplaySubject
. I am subscribing this ReplaySubject
variable into my component
.
My Code
@Injectable()
export class PersonService {
// The person subject
personStream: ReplaySubject<Person> = new ReplaySubject();
// Get person from DB and add to stream
getDataFromDB() {
this.http.get(url).subscribe(response => {
this.personStream.next(response.person);
});
}
}
@Component({...})
export class MyComponent implements OnInit {
person: Person;
constructor(private personService: PersonService) {}
ngOnInit() {
this.personService.personStream.subscribe(person => this.person = person);
}
}
This code is working fine, but I have a doubt. I have seen a code which is a little bit different from this approach. Another way of subscribing ReplaySubject
is to create a new function in the service, of type Observable
and inside the component subscribe to that function instead of subscribing the ReplaySubject
directly.
Example
@Injectable()
export class PersonService {
// The person subject
personStream: ReplaySubject<Person> = new ReplaySubject();
// The person observable
person$(): Observable<Person> {
return this.personStream.asObservable();
}
// Get person from DB and add to stream
getDataFromDB() {
this.http.get(url).subscribe(response => {
this.personStream.next(response.person);
});
}
}
@Component({...})
export class MyComponent implements OnInit {
person: Person;
constructor(private personService: PersonService) {}
ngOnInit() {
// Subscribe to person observable. Any time person data changes, this will be called.
this.personService.person$().subscribe(person => this.person = person);
}
}
I know both the way the code will work, but I want to know the best and efficient way of doing this.
Thanks.
Upvotes: 1
Views: 602
Reputation: 11982
the first way is for when you want to get the data from api and use it in your component and you have only one subject to subscribe it in component, assume you have a super subject that get the data from api and you have some subjects that are also observers of this super subject, they subscribe super subject and make change in data and naxt()
it to their observers, for example you have multiple components those have multiple elements those need data, components get the data from super subject and subscribe it and next()
them for their elements. for e.g :
public registerObserver(name): Observable<any> {
return this.observers[dataSourceName].observable.map((data: any) => {...}).catch((error: any) => {
return Observable.throw({ error, name });
});
}
public storeData(name, observable) {
observable.subscribe(data => {
if (this.observers[name]) {
this.observers[name].subject.next(data);
}
}, error => {
if (this.observers[name]) {
this.observers[name].subject.error(error);
}
});
}
Upvotes: 0
Reputation: 16451
Subscribing directly to ReplaySubject
is fine as you describe in the first method.
Making an observable from ReplaySubject
and subscribing to it (your second method) has one benefit. You cannot accidentally next()
value to an observable but it is possible in case of a Subject
such as ReplaySubject
. This is an additional safety in the cost of some little more codes.
Upvotes: 1