Reputation: 15050
I have this Product interface:
export interface Product{
code: string;
description: string;
type: string;
}
Service with method calling product endpoint:
public getProducts(): Observable<Product> {
return this.http.get<Product>(`api/products/v1/`);
}
And component where I use this service to get the Products.
export class ShopComponent implements OnInit {
public productsArray: Product[];
ngOnInit() {
this.productService.getProducts().subscribe(res => {
this.productsArray = res;
});
}
}
With this state I'm getting error:
[ts] Type 'Product' is missing the following properties from type 'Product[]': length, pop, push, concat, and 26 more. [2740]
Removing typing on productsArray
variable removes the error, but don't get why this is not working, since server response is an array of objects in the type of Products
?
Upvotes: 178
Views: 441323
Reputation: 121
You must specify which type the response is:
this.productService.getProducts().subscribe(res => {
this.productsArray = res;
});
Try this:
this.productService.getProducts().subscribe((res: Product[]) => {
this.productsArray = res;
});
Upvotes: 9
Reputation: 1287
For me the error was caused by wrong type hint of url string. I used:
export class TodoService {
apiUrl: String = 'https://jsonplaceholder.typicode.com/todos' // wrong uppercase String
constructor(private httpClient: HttpClient) { }
getTodos(): Observable<Todo[]> {
return this.httpClient.get<Todo[]>(this.apiUrl)
}
}
where I should have used
export class TodoService {
apiUrl: string = 'https://jsonplaceholder.typicode.com/todos' // lowercase string!
constructor(private httpClient: HttpClient) { }
getTodos(): Observable<Todo[]> {
return this.httpClient.get<Todo[]>(this.apiUrl)
}
}
Upvotes: 1
Reputation: 4471
I got the same error message on GraphQL mutation input object then I found the problem, Actually in my case mutation expecting an object array as input but I'm trying to insert a single object as input. For example:
First try
const mutationName = await apolloClient.mutate<insert_mutation, insert_mutationVariables>({
mutation: MUTATION,
variables: {
objects: {id: 1, name: "John Doe"},
},
});
Corrected mutation call as an array
const mutationName = await apolloClient.mutate<insert_mutation, insert_mutationVariables>({
mutation: MUTATION,
variables: {
objects: [{id: 1, name: "John Doe"}],
},
});
Sometimes simple mistakes like this can cause the problems. Hope this'll help someone.
Upvotes: 1
Reputation: 52534
This error could also be because you are not subscribing to the Observable.
Example, instead of:
this.products = this.productService.getProducts();
do this:
this.productService.getProducts().subscribe({
next: products=>this.products = products,
error: err=>this.errorMessage = err
});
Upvotes: 0
Reputation: 49
I had the same problem and I solved as follows define an interface like mine
export class Notification {
id: number;
heading: string;
link: string;
}
and in nofificationService write
allNotifications: Notification[];
//NotificationDetail: Notification;
private notificationsUrl = 'assets/data/notification.json'; // URL to web api
private downloadsUrl = 'assets/data/download.json'; // URL to web api
constructor(private httpClient: HttpClient ) { }
getNotifications(): Observable<Notification[]> {
//return this.allNotifications = this.NotificationDetail.slice(0);
return this.httpClient.get<Notification[]>
(this.notificationsUrl).pipe(map(res => this.allNotifications = res))
}
and in component write
constructor(private notificationService: NotificationService) {
}
ngOnInit() {
/* get Notifications */
this.notificationService.getNotifications().subscribe(data => this.notifications = data);
}
Upvotes: 2
Reputation: 2002
For those newbies like me, don't assign variable to service response, meaning do
export class ShopComponent implements OnInit {
public productsArray: Product[];
ngOnInit() {
this.productService.getProducts().subscribe(res => {
this.productsArray = res;
});
}
}
Instead of
export class ShopComponent implements OnInit {
public productsArray: Product[];
ngOnInit() {
this.productsArray = this.productService.getProducts().subscribe();
}
}
Upvotes: 17
Reputation: 29795
You are returning Observable<Product>
and expecting it to be Product[]
inside subscribe
callback.
The Type returned from http.get()
and getProducts()
should be Observable<Product[]>
public getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(`api/products/v1/`);
}
Upvotes: 164
Reputation: 3258
You have forgotten to mark the getProducts return type as an array. In your getProducts it says that it will return a single product. So change it to this:
public getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(`api/products/v1/`);
}
Upvotes: 28