Type 'Observable<Product[]>' is not assignable to type 'Product[]'.

36,468 views
Skip to first unread message

hhd...@gmail.com

unread,
Mar 9, 2018, 5:02:42 AM3/9/18
to Angular and AngularJS discussion
I get the following error in Angular when I try to copy the result of the http service into variable products. Any ideas please? I think this might be related to the mapping, which I'm unsure how to do. 
Btw I want to use HttpClient, not Http, and the mapping should be done automatically by using the get<type>("api/route"); syntax, right? 

    Error TS2322 (TS) Type 'Observable<Product[]>' is not assignable to type 'Product[]'.   Property 'includes' is missing in type 'Observable<Product[]>'.

Here is the code:


    import { HttpClient} from "@angular/common/http"
    import { Injectable } from "@angular/core"
    import { Product } from "./product";
    import { Observable } from "rxjs";
    
    
    @Injectable()
    export class DataService {
        constructor(private http: HttpClient) { }
    
        public products: Product[] = [];
    
        loadProducts(): Observable<Product[]>  {
            debugger;
            this.products = this.http.get<Product[]>("/api/products");
            return true;
        }
    }

The previous version, that worked, without typesafety, is (just for the record):

...
    
    @Injectable()
    export class DataService {
        constructor(private http: HttpClient) { }
    
        public products = [];
    
        loadProducts() {
            return this.http.get("/api/products")
                
                .map((data: any[]) => {
                    this.products = data;
                    return true;
                });
        }
    }

I am interested to make the example with type safety work, for this of course Product is defined in a .ts file like this:

    export interface Product {
        id: number;
        category: string;
        size: string;
        //...
    }

and I made sure the properties returned from the api match the properties from the interface.

Sander Elias

unread,
Mar 9, 2018, 11:43:48 AM3/9/18
to Angular and AngularJS discussion
Hi  hhdr104,

Yeah, that is not how observables or promises work. If you want to assign the payload of an observable to a property inside a class, do it inside a subscribe. Remeber that subscribing n a service is more or less an antipattern. 
You will run into race conditions if you do it like you are doing it in your example code.

The correct way would be something like:

    @Injectable()
   
export class DataService {
        constructor
(private http: HttpClient) { }

   
       
public products: Observable<Product[]> = of([]);
   
        loadProducts
(): Observable<Product[]>  {
           
debugger;
           
this.products = this.http.get<Product[]>("/api/products").pipe(shareReplay(1));
           
return this.products;
       
}
   
}

And then handle the observable properly wherever you use it. Preferable with the async pipe.

Regards
Sander

snehitha uday

unread,
Feb 12, 2019, 1:34:00 AM2/12/19
to Angular and AngularJS discussion
I have the similar issue, but not able to solve it even after the help provided below,
This is the component part 
         public policyinc: Observable<PolicyData[]> = of([]);


getIncCompany() {
        
        this.policyService.getIncCompany()
        .subscribe(data => {
            console.log(data);
this.policyinc = data,
(error: any) => this.errorMessage = <any>error,
       console.log(this.policyinc);
        }
         // this.vehicleDetailsForm.reset(),
    );
        }
And this on my service side 
getIncCompany(): Observable<PolicyData[]> {
const headers = new HttpHeaders({ 'Content-Type': 'application/json'});
let body = '{}';
return this.http
.post<PolicyData[]>(this.apiUrl, body, { headers: headers })
.pipe(
tap(data => console.log('getIncCompany: ' + JSON.stringify(data))),
catchError(this.handleError)
);
}

Scott Logsdon

unread,
Feb 15, 2019, 3:28:09 AM2/15/19
to ang...@googlegroups.com
Try wrapping the map inside pipe.  .pipe(map(

--
You received this message because you are subscribed to the Google Groups "Angular and AngularJS discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at https://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages