简体   繁体   中英

How to map array of objects in React js

I am trying to map the array which I get from API call to the state. Actually it maps elements of array in the correct count. However, I get only 1 st element of array n times(n length of array). Where I did mistake???

export default class NewCalendarView extends Component {
  componentDidMount() {
    API.getLectures().then((res)=>{
      console.log(res)
       let cal=res.map((lec)=>{
        let lecture={
        title: lec.subjectName,
        startDate : moment(lec.dateHour).toDate(),
        endDate:  moment(lec.dateHour).toDate()
        }  
        console.log("lec "+ JSON.stringify(lecture));
        return lecture;
             })
          this.setState({events:cal,loading:null,serverErr:null})
    }).catch((err)=>{
        this.setState({serverErr:true,loading:null})
    })
}
  constructor(props) {
    super(props);

    this.state = {
       events: []
    }
  }
  render() {
    return (
      <div style={{
        flex: 1
      }}>

        <Calendar
          localizer={localizer}
          events={this.state.events}
          startAccessor='startDate'
          endAccessor='endDate'
          views={['month', 'week', 'day']}
          culture='en'
          />
      </div>
    );
  }
}

json from API call

res: [{"subject":"SoftwareEngineering II","date":"2020-11-16","hour":"15:26","modality":"In person","room":"12A","capacity":150,"bookedStudents":100,"teacherName":"Franco yjtyjty","lectureId":1,"booked":false},{"subject":"SoftwareEngineering II","date":"2020-11-14","hour":"17:26","modality":"In person","room":"12A","capacity":50,"bookedStudents":100,"teacherName":"Franco yjtyjty","lectureId":2,"booked":false},{"subject":"SoftwareEngineering II","date":"2020-11-13","hour":"17:26","modality":"In person","room":"12A","capacity":50,"bookedStudents":100,"teacherName":"Franco yjtyjty","lectureId":3,"booked":false},{"subject":"SoftwareEngineering II","date":"2020-11-17","hour":"17:26","modality":"In person","room":"12A","capacity":50,"bookedStudents":100,"teacherName":"Franco yjtyjty","lectureId":4,"booked":false}]

Looks like the keys that you are trying to access do not exist in the res object. Try replacing the keys as defined below and that might help.

It can be confusing to match the parameters in the cloud and app at times especially with camelCase and kebab-case conventions!

let lecture= {
    title: lec.subject,
    startDate : moment(lec.date).toDate(),
    endDate:  moment(lec.date).toDate()
    }  

I would suggest removing this piece of code -

 let cal=res.map((lec)=>{
    let lecture={
    title: lec.subjectName,
    startDate : moment(lec.dateHour).toDate(),
    endDate:  moment(lec.dateHour).toDate()
    }  
    console.log("lec "+ JSON.stringify(lecture));
    return lecture;
         })

just do this instead -

this.setState({events:JSON.stringy(res),loading:null,serverErr:null})

also I noticed that there is no unique key , this is why its always the first object repeated n times

anyways I noticed Talha Azhar has already answered while I was typing my answer his answer will definitely help, also you can try doing what I suggest above it will also reduce your code.

You're mapping properties that don't exist in your response. You should store the lectureId to use it as key.

I'd also suggest you use a more idiomatic approach, using function components and hooks.

You can rewrite your component like this:

function NewCalendarView() {
  const [serverErr, setServerErr] = useState();
  const [loading, setLoading] = useState();
  const [events, setEvents] = useState();

  useEffect(() => {
    (async () => {
      try {
        const lectures = await API.getLectures();

        const cal = lectures.map(({ lectureId, subject, date }) => ({
          id: lectureId,
          title: subject,
          startDate: moment(date).toDate(),
          endDate: moment(date).toDate()
        }));

        setEvents(cal);
        setServerErr(null);
      } catch (e) {
        setEvents();
        setServerErr(true);
      }
      setLoading(null);
    })();
  }, []);

  return (
    <div
      style={{
        flex: 1
      }}
    >
      <Calendar
        localizer={localizer}
        events={events}
        startAccessor="startDate"
        endAccessor="endDate"
        views={["month", "week", "day"]}
        culture="en"
      />
    </div>
  );
}

I put a functional version in this sandbox: https://codesandbox.io/s/react-playground-forked-7sm6h?file=/index.js:2582-3523

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM