Syntactic Fructose Syntactic Fructose - 1 month ago 21
TypeScript Question

Type 'Observable<{}> is not assignable to type 'Observable'

To preface: I know there are a ton of other questions with this exact same error, but I still can't seem to figure out my own.

I have a simple service, and another simple component. I'm trying to follow the angular2 hero tutorial very closely, here is my code:

location.ts




export class Location {
name: string;
type: string;
c: string;
zmw: string;
tz: string;
tzs: string;
l: string;
ll: string;
lat: string;
lon: string;
}


location-search.service.ts




import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs';

import { Location } from './location';

@Injectable()
export class LocationSearchService {
constructor(private http: Http) {}

search(term: string): Observable<Location[]> {
return this.http
.get(`api_url_i've_removed`)
.map((r: Response) => r.json().data as Location[]);
}
}


location-search.component.ts




import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

import { LocationSearchService } from './location-search.service';
import { Location } from './location';

@Component({
selector: 'location-search',
templateUrl: 'location-search.component.html',
styleUrls: ['assets/styles.css'],
providers: [ LocationSearchService ]
})

export class LocationSearchComponent implements OnInit {
locations: Observable<Location[]>;
private searchTerms = new Subject<string>();

constructor(
private locationSearchService: LocationSearchService,
private router: Router) {}

search(term: string): void {
this.searchTerms.next(term);
}

ngOnInit(): void {
this.locations = this.searchTerms // <- ERROR HERE
.debounceTime(300)
.distinctUntilChanged()
.switchMap(term => term
? this.locationSearchService.search(term)
: Observable.of<Location[]>([]))
.catch(error => {
console.log(error);
return Observable.of<Location[]>([]);
})
}
}


I keep getting the error:

Type 'Observable<{}>' is not assignable to type 'Observable<Location[]>'.at line 29 col 9


Am I doing something obviously wrong? Thank you for any help

Answer

I can't tell you that exact problem, but I struggled over this few times too!

It's a problem with .switchMap(). Idk if it's an typescript problem or what.. Maybe just the typings file is bad..

You have to cast it:

ngOnInit(): void {
    this.locations = <Observable<Location[]>>this.searchTerms // <- ERROR HERE
        .debounceTime(300)
        .distinctUntilChanged()
        .switchMap(term => term
            ? this.locationSearchService.search(term)
            : Observable.of<Location[]>([]))
        .catch(error => {
            console.log(error);
            return Observable.of<Location[]>([]);
        })
}

Or (as you mentioned) use your functions switchMap() and catch() with an type, like this:

ngOnInit(): void {
    this.locations = this.searchTerms // <- ERROR HERE
        .debounceTime(300)
        .distinctUntilChanged()
        .switchMap<Observable<Location[]>>(term => term
            ? this.locationSearchService.search(term)
            : Observable.of<Location[]>([]))
        .catch<Observable<Location[]>>(error => {
            console.log(error);
            return Observable.of<Location[]>([]);
        })
}