Property 'forEach' does not exist on type '{}'

16,403

There's no way how TypeScript can be aware here that data is an array that has forEach method.

In order to fix this, data should be typed properly, like:

d3.json('../../../../assets/data/lukaku.json', function(error, data: any[]) {
  ...
})

Since d3.json is generic method, the right way to do this is to specify generic type:

d3.json<any[]>('../../../../assets/data/lukaku.json', function(error, data) {
  ...
})
Share:
16,403
tripstar
Author by

tripstar

Updated on June 09, 2022

Comments

  • tripstar
    tripstar almost 2 years

    I am working with Angular CLI and D3.js v4 and I keep getting a TypeScript error: Property 'forEach' does not exist on type '{}'. The error occurs on a forEach function when I try to bring in my data.

    I am following D3 Tips and Tricks which seems very extensive and helpful for the graphing library but unfortunately isn't helpful for my current problem.

    I know the path to my json file is correct bc I can console.log the data if my forEach function is commented out in my code.

    I also tried to define data before the forEach function in an effort to let Typescript know that data is an array.

    Any help is appreciated! Thanks!

    import { Component, OnInit } from '@angular/core';
    import * as d3 from 'd3';
    
    @Component({
        selector: 'pl-lukaku-graphs',
        templateUrl: './lukaku-graphs.component.html',
        styleUrls: ['./lukaku-graphs.component.scss']
    })
    export class LukakuGraphsComponent implements OnInit {
    
        constructor() { }
    
        total_min() {
            // create var for graph wrap
            let wrap = document.getElementById("wrapMinPlayed");
            // set up graph area
            let margin = {top: 30, right: 20, bottom: 30, left: 20},
                width = wrap.offsetWidth - margin.left - margin.right,
                height = wrap.offsetHeight - margin.top - margin.bottom;
            let data = [];
            d3.json('../../../../assets/data/lukaku.json', function(error, data) {
                console.log(data);
                console.log(error);
                if (error) throw error;
                // format data
                data.forEach(function(d) {
                    d.date = parseTime(d.date);
                    d.close = +d.close;
                });
            });
        }
    
        ngOnInit() {
            this.total_min();
        }
    
    }
    
    
    [
        {
            "season": "16/17",
            "match_day": "1",
            "opponent": "Spurs",
            "home_away": "Home",
            "final": "1-1",
            "status": "Not in squad",
            "min_played": 0,
            "goals": 0,
            "goal_min": [],
            "assists": 0
        }
    ]
    
  • tripstar
    tripstar almost 7 years
    Thank you so much! I was fairly certain the issue had something to do with the way I had typed data but I couldn't find a solution. Thanks again for your help!
  • Estus Flask
    Estus Flask almost 7 years
    @tripstar You're welcome. Most times a param would be implicitly typed as any and won't have such problem, but this case is different. That's why it is always a good idea to check type definition (in type files or IDE type suggestions).
  • tripstar
    tripstar almost 7 years
    thanks again. Was just about to jump on here and see if I could get a more in depth answer. Trying to learn as much as I can about ES6!