Neo
Neo

Reputation: 119

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}]

Upvotes: 0

Views: 269

Answers (3)

Talha Azhar
Talha Azhar

Reputation: 256

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()
    }  

Upvotes: 1

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

Upvotes: 0

shashwat gupta
shashwat gupta

Reputation: 81

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 .

Upvotes: 1

Related Questions