Why I am getting this error in forEach function

I am getting the following error while loading the below component:

TypeError: _this2.props.value.forEach is not a function
    fetchRecords webpack:///./src/main/js/components/forms/AutoCompanies.js?:122
    promise callback*fetchRecords webpack:///./src/main/js/components/forms/AutoCompanies.js?:115
    componentDidMount webpack:///./src/main/js/components/forms/AutoCompanies.js?:149
    React 6
    unstable_runWithPriority webpack:///./node_modules/scheduler/cjs/scheduler.development.js?:653
    React 5
    unstable_runWithPriority webpack:///./node_modules/scheduler/cjs/scheduler.development.js?:653
    React 6
AutoCompanies.js:143:24

And it is basically indicating this line of code this.props.value.forEach(e => { in the code below. I wonder why this is happening?

I came across this post with related error but unable to figure out it in my context.

import {Select as CompanySelect} from 'react-select-virtualized';

function escapeRegexCharacters(str) {
    return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

const override = css`
  display: block;
  margin: 0 auto;
  border-color: red;
`;

export class AutoCompanies extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            selectedCompanyValues: null,
            selectedCompanies: [],
            loading: false
        };
        
         this.onChange = this.onChange.bind(this)
        this.companyTemplate = this.companyTemplate.bind(this);
        this.selectedCompaniesTemplate = this.selectedCompaniesTemplate.bind(this);
    }

    companyTemplate(option) {
        return (
            <div className="country-item">
                <div>{option.label}</div>
            </div>
        );
    }

    selectedCompaniesTemplate(option) {
        if (option) {
            return (
                <div className="country-item country-item-value">
                    <div>{option.title}</div>
                </div>
            );
        }

        return "Select Cohorts";
    }

    onChange = (val) => {
       
        this.setState({
            value: val,
            selectedCompanyValues: val
        });
        this.props.onChange(val)
    };

    fetchRecords() {
        const loggedInUser = JSON.parse(sessionStorage.getItem("loggedInUser"));
        let url = isAdmin(loggedInUser) ? 'url1' : 'url2?value=' +  loggedInUser.id
       
        return axios
            .get(url)
            .then(response => {
                let selectedCompanies = [{title: 'test', label: this.props.value[0] && this.props.value[0].title}]
                if (this.props.value) {
                    this.props.value.forEach(e => {
                        selectedCompanies.push(response.data._embedded.companySets.filter(companySet => {
                            return companySet.companySetId === e.companySetId
                        })[0])
                    })
                }

              
                this.setState({

                   selectedCompanies: response.data._embedded.companySets.map(item => ({
                    label: item.title,
                    title: item.title,
                    companySetId: item.companySetId,
                })),
                    selectedCompanyValues: selectedCompanies
                });
            }).catch(err => console.log(err));
    }



    componentDidMount(){
        this.fetchRecords(0);
    }
    

    render() {
        return (
            <div>
                <CompanySelect value={this.state.selectedCompanyValues} options={this.state.selectedCompanies} onChange={this.onChange}  optionHeight={60}/> 

            </div>
        );
    }
}

The if statement before the forEach seems to be incomplete.

if (this.props.value) {

To more appropriately protect against the value not being an array, something like the following should do a better job:

if (Array.isArray(this.props.value)) {

This is React though which I don’t know anything about, so there may be a better React way of dealing with it, related to the question of why this.props.value is not an array to begin with.

Thanks. Sometimes it is an array and sometimes it is not and hence the issue.

This happens more than I’d like to admit. If theres a case where is sometimes is an array, sometimes not, try this pattern:

const myArray = Array.from(this.props.value)

You can then use array methods safely.

1 Like