Bhagwat Tupe
Bhagwat Tupe

Reputation: 1943

Angular 8 : TypeError: Found non-callable @@iterator

When i'am sending http get request then i'am getting these error TypeError: Found non-callable @@iterator,but it works in Angular 7 not in Angular 8.

My Component file
From component.ts file i have called service getCodes()

onSubmit(){
 this.service.getCodes('localhost/Aggregator/getCodes').subscribe (result=>{
 }, error =>{
    console.log(error);
 })
}

My Interceptor file
When i 'am sending request then that time i have passed these header through interceptor

@Injectable()
    export class Interceptor implements HttpInterceptor {
      sessionParam:any = {
        userParam: {
          'a':66,
          'b':101,
          'c':'0201',
          'd':'Y',
          'e':'Y',
          'h':'2019/02/22',
          'f':'Y',
          'g':12
        }
      }

      intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        let headers = new HttpHeaders();
        for (var val in this.sessionParam) {
          Object.keys(this.sessionParam[val]).forEach(key => {
            headers = headers.append(key,this.sessionParam[val][key]);
          });
        }
        request = request.clone({
          headers: headers
        })
        return next.handle(request);
      }
    }

My Service file

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { delay, map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ProvidersService {

  constructor(private http:HttpClient) { }

  public getCodes(url, apiParam=null):Observable<any>
  {
    return this.http.get(url, {params: apiParam});
  }
}

I'am getting following error

TypeError: Found non-callable @@iterator
at HttpHeaders.applyUpdate (http.js:301)
at http.js:245
at Array.forEach (<anonymous>)
at HttpHeaders.init (http.js:241)
at HttpHeaders.forEach (http.js:339)
at Observable._subscribe (http.js:1826)
at Observable._trySubscribe (Observable.js:42)
at Observable.subscribe (Observable.js:28)
at subscribeTo.js:20
at subscribeToResult (subscribeToResult.js:7)

any solutions ?

Upvotes: 21

Views: 69361

Answers (8)

In my case, I was also trying to deconstruct an object:

console.log('state: ', ...state)

But I forgot to create the object. The solution was to deconstruct it as object:

console.log('state: ', {...state})

Upvotes: 8

Aditya Mittal
Aditya Mittal

Reputation: 1771

return this.fooPipe.transform(foo, ...args);

-> Error: Found non-callable @@iterator

This error likely means you are trying to spread an object rather than an array in ES6/ES2015. In ES5 you could spread an object, all it would really do is spread its values. It was convenient, but you can easily still achieve this with a library like underscore or lodash by just getting the values and then spreading them. You can of course also just create the array yourself if you don't want to use a library. I prefer the following way:

const _ = require('underscore');

return this.fooPipe.transform(foo, ..._.values(args));

Upvotes: 0

Life347
Life347

Reputation: 17

All Header should be in string while using angular 8+

Upvotes: -2

Felix
Felix

Reputation: 4595

I have upgraded from A7 to A8 and experienced same issue.

In my case the code was failing on a row where I used destructuring assignment:

return this.fooPipe.transform(foo, ...args);

-> Error: Found non-callable @@iterator

It has helped me to change tsconfig.json from:

"target": "es2015"

to

"target": "es5"

Upvotes: 12

Got same error today, my solution to this was to work with iterations on Object and then create HttpHeaders with the result. Kinda ...

    let headersObj = {};

    for (var val in this.sessionParam) {
      Object.keys(this.sessionParam[val]).forEach(key => {
        headersObj[key] = this.sessionParam[val][key];
      });
    }
    request = request.clone({
      headers: new HttpHeaders(headersObj)
    })

Upvotes: 0

Tasneem Ghorayeb
Tasneem Ghorayeb

Reputation: 89

This is not a new solution but maybe it helps someone.

I have faced this issue as well after upgrading to angular 8. It threw an error where I used Object.assign({},), it was working before.

I did not want to change all my code where I was using this in favor of the spread operator because it was way too many changes.

It worked when I changed the target back to es5. But I was not sure this is the right move.(I'm still not sure what could be the pros of this.)

After a lot of searching I came upon this link https://kangax.github.io/compat-table/es6/#typescript-core-js-note So here it states that for Object.assign to work, I need to have

typescript > 3.6 & core-js >= 3

Currently angular 8 requires typescript to be less than 3.6 I am guessing this is the reason of the error, so until angular 8 supports the this typescript version or angular 9 does, I guess I will be using the same approach as Felix.

Upvotes: 0

David
David

Reputation: 924

This error occurs when you set headers non-string values. In order to solve convert all header values to string.

Upvotes: 26

Davis
Davis

Reputation: 99

Can't comment, but I'd recommend you look at the data ending up in your headers object. Maybe you could log the contents of headers just before the return next.handle(request); line. You could find, for example, that one of the values provided by this.sessionParam[val][key] is not a string and a simple this.sessionParam[val][key] + '' could do the trick...

Upvotes: 3

Related Questions