Reputation: 5903
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
Upvotes: 7
Views: 16511
Reputation: 37353
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
Upvotes: 6
Reputation: 40647
There are many errors in your code
There isn't a this.recruiters
field in your service
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
Upvotes: 5