Emptyform2017-08-03 09:43:25
Emptyform, 2017-08-03 09:43:25

[Angular] Selecting data for a dropdown list (typeahead) - is it done right?

Task: to write a drop-down list - as you type in <input>, show a drop-down list where the data is filtered according to the entered string.
Data selection done like this:

Observable.fromEvent(this.myInput.nativeElement, 'input')
  .map(e => e.target.value)
  .subscribe(searchText => {
      .map(res => res.json())
      .subscribe(users => {
        this.userNames =
          users.map(item => item.fullName)
               .filter(item => item.toLowerCase().includes(searchText.toLowerCase()))

The code is simplified for clarity (removed the indication of types, a pause after the end of the input, checking the length of the entered string, etc.)
Is this a normal option or can it be better?
In general, I'm confused by subscribe inside another subscribe

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Makito, 2017-08-05

Well, firstly, the search itself seems to work strangely for you, it turns out that every time you load all users and then search locally for occurrences using this selection.
You either need to load the entire list of users once during initialization and put it, for example, in _source and then, when entering text, filter this list and not torment the server with requests, or if there are a lot of users, then a method must be implemented on the server to search for employees by line.
Secondly, yes, the code is written not quite correctly.
If you want the server to look for and return only the appropriate one:

Observable.fromEvent(this.myInput.nativeElement, 'input')
    .map(e => e.target.value)
    .switchMap(searchText => this.http.get(`URL_API&q=${searchText}`))
    .map(res => res.json())
    .subscribe(users => this.userNames = users);

If you want to search through a locally stored collection of users then:
Observable.fromEvent(this.myInput.nativeElement, 'input')
    .do(e => this.searchText = e.target.value)
    .switchMap(() => Observable.from(this._source))
    .subscribe(users => this.userNames = users.map(item => item.fullName)
               .filter(item => item.toLowerCase().includes(searchText.toLowerCase())));

My code may not be 100% working, but the general message should be.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question