Arpit Kumar
Arpit Kumar

Reputation: 2249

Can we subscribe a RxJs subject directly in Angular 4 component?

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

Answers (2)

Lia
Lia

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

siva636
siva636

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

Related Questions