skip to Main Content

This might be a little long, but I will try to keep it brief. For background. I am building a Calendar app using React, react-calendar and date-fns.

I am trying to extract values from an array of object in a forEach loop.

The array is:

datesToAddContentTo = [
    {date: '2023-11-24T22:00:00.000Z', user: 'Hilsie', isValid: true},
    {date: '2023-11-25T22:00:00.000Z', user: 'Hilsie', isValid: true},
    {date: '2023-11-26T22:00:00.000Z', user: 'Hilsie', isValid: true},
    {date: '2023-11-27T22:00:00.000Z', user: 'Hilsie', isValid: true} 
]

Below is the code of how the array is being created:

const datesToAddContentTo = [
    dateList.map((item) => {
      return {
        date: item.fullDate,
        user: item.user,
        isValid: isValid(
          parse(String(item.fullDate), "yyyy-MM-dd'T'HH:mm:ss.SSSX", new Date())
        ),
      };
    }),
  ];

console.log(datesToAddContentTo);

After creating the array I am then trying to extract the values of the array so I can use it to validate/compare the dates to the date on a Calendar so I can display info on the calendar tiles. Below the code that I use to do this:

const tileContent = useCallback(({ date, view }) => {
    datesToAddContentTo.forEach((obj) => {
      let user = obj.user;
      console.log("This is: " + user);
      let sDate = parse(
        String(obj.date),
        "yyyy-MM-dd'T'HH:mm:ss.SSSX",
        new Date()
      );
      console.log("sDate is: " + sDate);
      let tDate = date;
      console.log("sDate: " + sDate + ". tDate: " + tDate);
      if (view === "month") {
        if (isSameDay(sDate, tDate)) {
          return <p className={`success ${user}`}>Success</p>;
        } else {
          return <p className="fail">NOT Success</p>;
        }
      }
    });
  }, []);

What I was expecting here was for the date to be extracted from the array as I have done on many occasions and to then be able to parse and compare the dates. What I see however is that the values from the array are returned/extracted as undefined.

I believe I need to be digging a little deeper since I have an array of object, but I am not certain if that is indeed what is causing my problem.

2

Answers


  1. When creating datesToAddContentTo, you’re wrapping the result of dateList.map() in an additional array. This is unnecessary and makes datesToAddContentTo an array of arrays. You can remove the extra square brackets.

    const datesToAddContentTo = dateList.map((item) => {
      return {
        date: item.fullDate,
        user: item.user,
        isValid: isValid(
          parse(String(item.fullDate), "yyyy-MM-dd'T'HH:mm:ss.SSSX", new Date())
        ),
      };
    });
    

    The forEach function doesn’t return anything, so it’s not suitable for what you’re trying to achieve. You should use map instead, and then use find or filter to check if there’s a matching date in the array.

    const tileContent = useCallback(({ date, view }) => {
      const content = datesToAddContentTo.map((obj) => {
        let user = obj.user;
        let sDate = parse(
          String(obj.date),
          "yyyy-MM-dd'T'HH:mm:ss.SSSX",
          new Date()
        );
        let tDate = date;
    
        if (view === "month" && isSameDay(sDate, tDate)) {
          return <p className={`success ${user}`}>Success</p>;
        }
    
        return null;
      });
    
      // Use find or filter based on your requirements
      const matchingContent = content.find((item) => item !== null);
    
      return matchingContent || <p className="fail">NOT Success</p>;
    }, [datesToAddContentTo]);
    
    Login or Signup to reply.
  2. The array is:

    No it isn’t. You’ve assumed that it is, rather than debugged and observed. Look at how you’re building the array:

    const datesToAddContentTo = [
      dateList.map((item) => {
        //...
      })
    ];
    

    The result of .map() is an array. So your structure would become:

    const datesToAddContentTo = [
      [
        //...
      ]
    ];
    

    You have an array which contains an array. So in the call to .forEach():

    datesToAddContentTo.forEach((obj) => {
    

    The value of obj is an array. And arrays have no properties called user or date, so those values are undefined.

    The simplest fix is probably to just remove the enclosing array notation when creating your array:

    const datesToAddContentTo = dateList.map((item) => {
      //...
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search