angular 5 material 2 - auto complete getting data from external api

后端 未结 1 1382
太阳男子
太阳男子 2021-02-08 00:48

I\'m using angular 5 and material 2.

In ts file, I have this proeperty:

      filteredOptions: Observable;

This property i

1条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-02-08 01:25

    I see some issues, for example you should map(val => this.getArrayOfValue(val)). But I would also suggest some additional changes. Think about adding debounceTime, distinctUntilChanged and switchMap. Set a debounce time of your choosing. This, not to completely overload the api. As well as switchMap is useful to make the request switches to the last value user has typed. Also you should consider using a service for your api requests, that is usually how we handle things. So I suggest moving the http-request to the service and call that from the component.

    TS:

      // inject your created service which makes the http-request
      constructor(private service: Service) { 
    
      this.filteredOptions = this.myControl.valueChanges
            .pipe(
              startWith(''),
              debounceTime(400),
              distinctUntilChanged(),
              switchMap(val => {
                return this.filter(val || '')
              })       
            );
      }
    
      // filter and return the values
     filter(val: string): Observable {
        // call the service which makes the http-request
        return this.service.getData()
         .pipe(
           map(response => response.filter(option => { 
             return option.name.toLowerCase().indexOf(val.toLowerCase()) === 0
           }))
         )
       }  
    }
    

    Service would then call the http-request. If you do not overload the API, we could store the data in a variable after first fetch, and instead return an observable of that variable, but that is just optional.

    opts = [];
    
    getData() {
      return this.opts.length ?
        of(this.opts) :
        this.http.get('https://jsonplaceholder.typicode.com/users').pipe(tap(data => this.opts = data))
    }
    

    Also you seem to use value for your option in template. If you want to capture the whole object, use [value].

    Here's a DEMO for you to play around with :)

    0 讨论(0)
提交回复
热议问题