Typescript: Type X is missing the following properties from type Y length, pop, push, concat, and 26 more. [2740]

AngularTypescriptTypescript Typings

Angular Problem Overview


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?

Angular Solutions


Solution 1 - Angular

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/`);
}

Solution 2 - Angular

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/`);
  }

Solution 3 - Angular

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();
    }
}

Solution 4 - Angular

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;
});

Solution 5 - Angular

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);
}

Solution 6 - Angular

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.

Solution 7 - Angular

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
   });

Solution 8 - Angular

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)
  }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmproView Question on Stackoverflow
Solution 1 - AngularAmit ChigadaniView Answer on Stackoverflow
Solution 2 - AngularFredrik_BorgstromView Answer on Stackoverflow
Solution 3 - AngularBrady HuangView Answer on Stackoverflow
Solution 4 - AngularJonathan Cedrim De SouzaView Answer on Stackoverflow
Solution 5 - AngularShah Shahid View Answer on Stackoverflow
Solution 6 - AngularNipun RavisaraView Answer on Stackoverflow
Solution 7 - Angularlive-loveView Answer on Stackoverflow
Solution 8 - AngularMichał JabłońskiView Answer on Stackoverflow