Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type Observable<Observable<any[]>> is not assignable to type Observable<any[]>

I am implementing autocomplete with data from database service:

@Injectable()
export class SchoolService {
  constructor(private db: AngularFirestore) {
  }

  getSchools(): Observable<School[]> {
    return this.db.collection<School>('schools').valueChanges();
  }
}

In my component:

export class SchoolComponent implements OnInit {
  formControl: FormControl = new FormControl();
  schools: Observable<School[]>;
  filteredSchools: Observable<School[]>;

  constructor(private schoolService: SchoolService) {
  }

  ngOnInit() {
    this.schools = this.schoolService.getSchools();

    //Below line gives error "Type Observable<Observable<School[]>> is not assignable to type Observable<School[]>".
    this.filteredSchools = this.formControl.valueChanges.pipe(
      startWith(''),
      map(name => this.filterSchools(name))
    );
  }

  filterSchools(name: string): Observable<School[]> {
    return this.schools.map(school => school.filter(s => s.name.toLowerCase().includes(name)));
  }
}

And my html:

<form>
  <mat-form-field>
    <input type="text" matInput placeholder="Type Your School to Continue" [matAutocomplete]="auto"
           [formControl]="formControl">
    <mat-autocomplete #auto="matAutocomplete">
      <mat-option *ngFor="let school of filteredSchools | async" [value]="school">
        <span>{{school.name}}</span> |
        <small>{{school.city}}</small>
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</form>

The function in ngOnInit gives Type Observable<Observable<School[]>> is not assignable to type Observable<School[]> error. How can I fix this?

like image 733
6324 Avatar asked Dec 11 '22 07:12

6324


1 Answers

The error says exactly what's wrong. You defined:

filteredSchools: Observable<School[]>;

but later you create an Observable that emits (maps each value) results of filterSchools(name: string): Observable<School[]> which returns an Observable as well so at the end you have an Observable chain of Observable<Observable<School[]>>.

It actually looks like you just wanted to use switchMap (or mergeMap or concatMap) instead of map. switchMap will subscribe to the nested Observable and turn the chain into Observable<School[]>:

this.filteredSchools = this.formControl.valueChanges.pipe(
  startWith(''),
  switchMap(name => this.filterSchools(name))
);
like image 90
martin Avatar answered May 15 '23 13:05

martin