How to insert an initial value for an async list in an ng-select (Angular 2+, ng-select, and rxjs)

1k Views Asked by At

I am using ng-select and specifically using typeahead to fetch the list from the server as user types. like this:

defining an observable of Agents list to subscribe to whenever a string is inserted

agents$: Observable<Agent[]>
agentsInput$ = new Subject<string>();

notice here i am mapping the Agents to a specific desired object:

loadAgents() {
    this.agents$ = concat(
      of([]),
      this.agentsInput$.pipe(
        distinctUntilChanged(),
        tap(() => this.agentsLoading = true),
        switchMap(term => this.obexService.searchAgents(term).pipe(
          map(agent => agent.map(agent => ({
            id: agent._id,
            name: `${agent.firstName} ${agent.lastName}`
          }))),
          catchError(() => of([])), // empty the agents list on error
          tap(() => this.agentsLoading = false)
        ))
      )
    )
  }

here is the HTML:

<ng-select 
    id="contact-person" 
    labelForId="contact-person" 
    [items]="agents$ | async" 
    bindValue="id" 
    bindLabel="name"
    [loading]="agentsLoading" 
    typeToSearchText="Please enter 3 or more characters"
    [typeahead]="agentsInput$" 
    class="custom" 
    notFoundText="Agent Not Found"
    formControlName="contactAgent" 
    placeholder="Select a contact person">
  </ng-select>

basiclly what I am trying to do is to insert an initial list to agents$, so that to be able to set a default agent on the form control, so I want to turn the agent$ into behaviuor subject

sonmething like this:

agents$: BehaviorSubject<Agent[]> = new BehaviorSubject([{id: '123', name: 'john doe'}])

Now I have 2 problems:

1- how do I map agents on setting initial value the same way I mapped them in loadAgents() method?

2- The telesense shows the below error when setting the agents$ in the loadAgents() method

Type 'Observable<any[]>' is missing the following properties from type 'BehaviorSubject<Agent[]>': _value, value, getValue, next, and 9 more.ts(2740)

please advise.

1

There are 1 best solutions below

0
On

it seems you don't need the behavior subject. just the of observable should work for your case

agents$ = new of<Agent[]>([{id: '123', name: 'john doe'}]); // correct type will be applied in this case. no need to define it explicitly.
...

also for concact(of(something), ...) case there is a built in operator startWith

loadAgents() {
    this.agents$ = this.agentsInput$.pipe(
        // your code
        startWith<Agent[]>([])
      );