Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subscribing to Observable in service from component

I have searched for quite some time to understand how to subscribe to an array whose values are constantly updated.

I need to understand how to setup my Angular 2+ service observable correctly and subscribe to it in my component correctly. Please assume all other parts of the code works correctly.

@Injectable()
export class AutocompleteService {

    searchTerm: string;
    results = [];
    observe$ = Observable.from(this.results);

    searchTest(term){
        this.searchTerm = term.toLowerCase();

        if(this.searchTerm.length > 2){
            this.recruiters.forEach(function(el){
                if(el.name.toLowerCase().indexOf(term) != -1) {
                    this.results.push(el);
                }   
            });    

        }
    }

    getCurrentResults():Observable<Object> {
        return this.observe$;
    }

Everything in the service works as expected. If I log the term I get user input from my component. Or the results array after matching search results are pushed onto it.

@Component({
    selector: 'autocomplete',
    templateUrl: './autocomplete.component.html',
    providers: [AutocompleteService]
})
export class AutocompleteComponent implements OnInit{
    constructor(private autocompleteService: AutocompleteService){}

    value: string = '';
    searchControl = new FormControl();

    // fired when input happens
    getResults(event){
        this.autocompleteService.searchTest(event.target.value);

        this.autocompleteService.getCurrentResults().subscribe(
            value => console.log(value)
        );

    }

I have setup the observable pattern to the best of my ability but I'm not getting anything out of the .subscribe in getResults

like image 632
Ben Racicot Avatar asked Mar 30 '17 16:03

Ben Racicot


People also ask

Can you subscribe to an observable?

Executing an Observable But the observable function does not emit any values until it is executed. The subscribe() method calls the observable's function that produces and emits data. Thus, subscribing to an observable starts a flow of data between the observable and the observer.

Do I need to unsubscribe from observable in service?

You don't need to unsubscribe from observable created by Http or HttpClient because it is finite observable (value will be emitted only once and complete will be called). However, you CAN unsubscribe from the observable created by HttpClient to cancel the request.

Can we subscribe in Angular service?

Normally Subscription means an arrangement to receive something. Similarly, in Angular applications Observables will be connected to observers and whenever they observe a new value or change in data, they will execute code with the help of Subscription and all the subscribed components will receive the updated outcome.

What does subscribing to an observable mean?

The Subscribe operator is the glue that connects an observer to an Observable. In order for an observer to see the items being emitted by an Observable, or to receive error or completed notifications from the Observable, it must first subscribe to that Observable with this operator.


2 Answers

I addition to what jonrsharpe and echonax said:

you can use Subject :

@Injectable()
export class AutocompleteService {

    searchTerm: string;
    results = [];
    subject = new Subject();

    searchTest(term){
        this.searchTerm = term.toLowerCase();

        if(this.searchTerm.length > 2){
            this.recruiters.forEach(el =>{
                if(el.name.toLowerCase().indexOf(term) != -1) {
                    this.subject.next(el);
                }   
            });    

        }
    }

    getCurrentResults():Subject<Object> {
        return this.subject;
    }

}

and subscribe to getCurrentResults() the same way you did.

you demo : plunker

like image 184
El houcine bougarfaoui Avatar answered Nov 15 '22 08:11

El houcine bougarfaoui


There are many errors in your code

  1. There isn't a this.recruiters field in your service

  2. this.results.push(el); won't push anything to results because you are using forEach(function(el){ it should've been forEach((el)=> so that your this inside the scope would refer to your service.

Example plunker: http://plnkr.co/edit/5L0dE7ZNgpJSK4AbK0oM?p=preview

like image 34
eko Avatar answered Nov 15 '22 07:11

eko