andy wilson
andy wilson

Reputation: 970

TypeError: Cannot read property 'map' of undefined React Js

I am trying to push some data through using an array to a grandchild class, What I have is an array of id, summary, details which im using id for the key, summary is like a header, and details is hidden till you click the summary.

FAQ.js page

import React from "react";
import Accordions from '../components/Parts/Accordions';

let AccData = [
   {
     id: 1,
     summary: 'What Loans Do You Provide?',
     details: 'We lend £200 to £3,000 and have repayment terms from 6 
     months, 12 months, 15 months, 18 months or 24 months. You are welcome 
     to apply for a loan of any amount, however your approval will be 
     dependent on credit and affordability checks.',},
  {
     id: 2,
     summary: 'What Loan Terms Do You Offer?',
     details: 'You can borrow between £200 and £400 over a 6 month term. You 
     can borrow between £401 and £850 over a 12 month term. You can borrow 
     between £851 and £1,500 over a 15 month term. You can borrow between 
     £1,501 and £2,000 over a 18 month term, and you can borrow between 
     £2,001 and £3,000 over a 24 month term.'},
  {
     id: 3,
     summary: 'Can I Apply For A Loan?',
     details: 'To be eligible to apply for a loan, you must be at least 18 
     years old, a UK resident and have a UK bank account and debit card. You 
     must also have a net income of at least £700 per month, and be able to 
     comfortably afford the loan repayments.'
  }];

  export default class FAQ extends React.Component {
    render() {

      const hrStyle = {
         lineHeight:"10px",
         margin:"0",
         backgroundColor:"#3ba6f2",
         color:"#3ba6f2",
         border: "solid 2px #3ba6f2",
         width:"100%",
      }

      return (
    <div>
        <div className="container">
            <h1>Frequently Asked Questions</h1>
            <p>&nbsp;</p>
            <h4>The Basics</h4>
            <Accordions AccData={this.props.AccData}/>

        </div>
    </div>
    );
  }
 }

Accordions.js

import React from 'react';
import Accordion from './Accordion';

export default class Accordions extends React.Component {
    render(){
        return(
            <ul>
                {this.props.AccData.map((summ)=> {
                    return <Accordion summ={summ} key={summ.id} />
                })}
            </ul>
        );
    }
}

Accordion.js

import React from 'react';

const styles = {
    active: {
        display: 'inherit',
    },
    inactive: {
        display: 'none',
    }
};

export default class Accordion extends React.Component {
    constructor(){
        super();
        this.state = {
            active: false
        };
        this.toggle = this.toggle.bind(this);
    }

    toggle(){
        this.setState({
            active: !this.state.active
        });
    }

    render(){

        const stateStyle = this.state.active ? styles.active : styles.inactive;

        const hand = {
            cursor:"pointer",
        }

        return (
            <li>
                <p onClick={this.toggle} style={hand}>
                    {this.state.active ? "▼" : "►"} {this.props.summ.summary}
                </p>
                <p style={stateStyle}>
                    {this.props.summ.details}
                </p>
            </li>
        )
    }
}

Sorry For messy code i just really don't know why map is undefined i followed a tutorial except from renaming things

Upvotes: 0

Views: 578

Answers (3)

Lennholm
Lennholm

Reputation: 7480

In your FAQ.js, AccData is just a local variable, it's not a memeber of this.props.

Change

<Accordions AccData={this.props.AccData}/>

... into

<Accordions AccData={AccData}/>

Upvotes: 1

Stephen L
Stephen L

Reputation: 2339

Change your code to this:

return (
<div>
    <div className="container">
        <h1>Frequently Asked Questions</h1>
        <p>&nbsp;</p>
        <h4>The Basics</h4>
        <Accordions AccData={AccData}/>

    </div>
</div>
);

You define AccData in the FAQs.js page so just pass them in normally. They'll be in scope since you defined it outside of your class. You're getting undefined because this.props.AccData does not exist in your FAQs.js file. It will, however, exist in Accordions.js since you're passing it down as a prop.

Upvotes: 0

Ved
Ved

Reputation: 12103

The reason is AccData need to be sent to child component like this. And AccData={this.props.AccData} should be AccData={AccData}

 return (
    <div>
        <div className="container">
            <h1>Frequently Asked Questions</h1>
            <p>&nbsp;</p>
            <h4>The Basics</h4>
            <Accordions AccData={AccData}/>

        </div>
    </div>
    );

Upvotes: 2

Related Questions