Angular - Type '{}' is missing the following properties from type 'any[]'

Viewed 1163

In my Angular project i receive this error: Type '{}' is missing the following properties from type 'any[]'

I have a simple angular code with a helper-class making a request to url, which sends back a JSON array like [ {a: b, c: d}, {e: f} ... ] and everything works fine, with the expected results, but when i try to return the results to the main page.

I'd keep enforced the type, but don't know what i might need to resolve this error and want to understand it.

I'm obv open to questions about the code.


HelpClass

export class ExampleJsonGetter{
  constructor(private http: HttpClient) {
  }

  getArray() {
    return new Promise((resolve, reject) => {
      this.http.post<any>('https://anUrl.com/getjsonarray')
        .subscribe({
          next: data => {
            resolve(data);
          },
          error: error => {
            reject(error);
          }
        });
    });
  }
}

Main Page Class

export class MainPage{
  variable = [];
  constructor(){
    example.getArray().then((data)=>{
/*★*/ variable = data;  /* ★ */
      console.log(variable); // on firefox: 'Array(12): ...' As expected
      console.log(typeof variable); // 'object', souldn't it be Array?
    }).catch(e=>console.error(e));
  }
}

The only way it seems to work is replacing with variable = new Array( ...data);

I don't even know what those triple dots do,can you explain me?.

2 Answers

This is a typescript error indicating a type mismatch. Lets consider below

getArray() {
    return new Promise((resolve, reject) => {
      this.http.post<any>('https://anUrl.com/getjsonarray')
        .subscribe({
          next: data => {
            resolve(data);
          },
          error: error => {
            reject(error);
          }
        });
    });
  }

getArray() will return Promise<any> since the line this.http.post<any>('https://anUrl.com/getjsonarray') returns any

In the main page you have variable = []; indicating type any[]. So you are trying to assign type any to type any[] which will throw error.

To solve this change the line to this.http.post<any[]>('https://anUrl.com/getjsonarray')

It is best if you'll use either Subscription or Promise not combining them in a single http call.

Helper

import { throwError, Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';


export class ExampleJsonGetter {
   ...
   getArray(): Observable<any> {
     return this.http
       .post<any>('https://anUrl.com/getjsonarray')
       .pipe(catchError(err => throwError(err)))              // Catch and throw error

   }
}

If the above endpoint sends an object instead of an array, you can convert the response to an array by adding this to your pipe

import { toArray } from 'rxjs/operators';
getArray(): Observable<any[]> {                   // Now in any[] type
  return this.http
     .post<any>('https://anUrl.com/getjsonarray')
     .pipe(
       toArray(),                                // Add this
       catchError(err => throwError(err))
     )             
}

MainPage

example
  .getArray()
  .subscribe(
    data => console.log(data, Array.isArray(data))      // Check the data and confirm if it's an array
    err => console.error(err)                           // Console any error if there's any

  )       
Related