Type 'Observable<Object>' is not assignable to type 'Observable<IUser[]>'

44,943

Solution 1

There are two ways to do this, and it depends on which version of RxJS / Angular that you are using. Here are the two ways to do it depending on your versions:

// Using RxJS v4 / Angular v2-4. I assume that you're using the HttpModule...
import 'rxjs/add/operator/map';

public getUsers(url: string): Observable<IUser[]> {
  return this._http.get(url)
    .map((response: Response) => <IUser[]>response.json());
}


// Using RxJS v5 / Angular 5+ (at the moment). I assume that you're using the HttpClientModule, as the HttpModule was deprecated in Angular v4.
public getUsers(url: string): Observable<IUser[]> {
  return this._http.get<IUser[]>(url);
}

Solution 2

Typical, that 5 mins after I post, I find a solution.

Trick was to cast the .get function in the service the same as the type on the getUsers function as below:

public getUsers(url: string): Observable<IUser[]>  {
    return this._http.get<IUser[]>(url);
  }

Hope this helps other people out as well

Solution 3

in my case the below worked

  getUsers(): Observable<User[]> {
      return <Observable<User[]>> this.http.get(this.pathAPI + 'user', super.header())
      .pipe(catchError(super.handleError));
   }

I am using Angular 6

Share:
44,943
Sam Kelham
Author by

Sam Kelham

Updated on April 25, 2021

Comments

  • Sam Kelham
    Sam Kelham about 3 years

    In my Api service I have this simple getUsers function to fetch all of the users on the api.

    public getUsers(url: string): Observable<IUser[]>  {
      return this._http.get(url);
    } 
    

    This is my IUser interface, I have made all the field optional for now.

    export interface IUser {
      id?: string;
      first_name?: string;
      last_name?: string;
      location?: string;
      followers?: string;
      following?: string;
      checkins?: string;
      image?: string;
    }
    

    and here is how I have used the service in my component:

    export class SocialOverviewContainerComponent implements OnInit {
      public userData = [];
      public showForm = {};
      private _apiService: ApiService;
    
      constructor(apiService: ApiService) {
        this._apiService = apiService
      }
    
      public ngOnInit(): void {
        this.getUsersData();
      }
    
      public getUsersData()  {
        this._apiService.getUsers(ApiSettings.apiBasepath + 'users/')
          .subscribe(users => {
            this.userData = users;
        })
      }
    }
    

    and this is is the Type error I get when it compiles

    ERROR in src/app/services/api.service.ts(18,5): error TS2322: Type 'Observable<Object>' is not assignable to type 'Observable<IUser[]>'.
      Type 'Object' is not assignable to type 'IUser[]'.
        The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?
          Property 'includes' is missing in type 'Object'.
    

    I thought this might be because my response doesn't match the interface, which I have double check and it does. And I have also made the field optional for now to make sure.

    I know I can fix this by casting the observable as any, but doesn't that defeat the point of using Typescript?

    Any help on where I am going wrong would be great

    Thanks in advance

  • Sam Kelham
    Sam Kelham about 6 years
    Yes it is HttpClientModule :)
  • AsGoodAsItGets
    AsGoodAsItGets almost 6 years
    The 2nd part of the answer about RxJS/Angular 5+ is wrong, the casting has to be done after the _.http.get function, as described below in @sam-kelham's answer.
  • th3n3wguy
    th3n3wguy almost 6 years
    @AsGoodAsItGets => I updated my answer to reflect your response. Thank you for letting me know!
  • Christian Matthew
    Christian Matthew almost 5 years
    this is still not working for me and it's exactly what I am doing
  • greg
    greg almost 4 years
    yikes, it took me 2 days to figure out which question to ask!