-1

I have the following object to be pushed to the an empty array [ ] EVENTS_DRAFT, in a React project.

let obj_submit = {
  id: createEventId(),
  templateId: task.id,
  title: task.title,
  type: task.type,
  description: task.description,
  duration: [
    CustomUtil.formatTimelessDate(calDate.toDateString(), true),
    CustomUtil.formatTimelessDate(calDate.toDateString(), true),
  ],
  assignees: false,
  points: task.points,
  completed: false,
  color: task.color,
};

EVENTS_DRAFT.push(obj_submit);

console.log(EVENTS_DRAFT); 

However, the duration property(which is an array of strings) is causing the push to fail, giving me this when I log EVENTS_DRAFT:

enter image description here

If I comment out the duration property, I can push fine, which gives me:enter image description here

I am confused as to why is the case. All my code below if needed.

event_draft.js

export const EVENTS_DRAFT = [];

getCreateTasks.js

import { EVENTS, createEventId } from "../../fakeDb/events";
import { TASK_TEMPLATES } from "../../fakeDb/task_templates";
import _ from "lodash";
import CustomUtil from "../../helpers/CustomUtil";
import turnCalculator from "../../helpers/turnCalculator";
import { EVENTS_DRAFT } from "../../store/stateless/dates_assignees";

const getCreateTasks = (calDate) => {
  const day_tasks = _.filter(EVENTS, (task) => {
    const task_date = new Date(task.duration[0]);
    return task_date.getTime() == calDate.getTime();
  });

  const day_templateIds = day_tasks.map((task) => {
    return task.templateId;
  });

  TASK_TEMPLATES.forEach((task) => {
    task.days.forEach((day) => {
      let unified_day = day;
      let cell_day;

      if (task.type === "monthly") {
        cell_day = calDate.getDate();
        if (day === "month end") {
          unified_day = CustomUtil.getMonthLastDate(calDate);
        }
      } else {
        cell_day = calDate.getDay();
      }

      if (
        cell_day == unified_day &&
        !day_templateIds.includes(task.id) &&
        calDate.getTime() >= new Date(task.beginDate).getTime()
      ) {
        let obj_submit = {
          id: createEventId(),
          templateId: task.id,
          title: task.title,
          type: task.type,
          description: task.description,
          //   duration: [
          //     CustomUtil.formatTimelessDate(calDate.toDateString(), true),
          //     CustomUtil.formatTimelessDate(calDate.toDateString(), true),
          //   ],
          assignees: false,
          points: task.points,
          completed: false,
          color: task.color,
        };

        EVENTS_DRAFT.push(obj_submit); // <=== pushing here
      }
    });
    if (EVENTS_DRAFT.length != 0) {
      turnCalculator(task.id, calDate);
    }
  });
};

export default getCreateTasks;

CustomUtil.js

class CustomUtil {
  static formatTimelessDate(
    day, //calDate.toDateString()
    typeString = false,
    offset = {
      offsetType: null,
      amount: 0,
    }
  ) {
    let dayPDT = new Date(day + " 01:00:00 GMT-0700 (Pacific Daylight Time)");
    let year = dayPDT.getFullYear();
    let month = dayPDT.getMonth();
    let date = dayPDT.getDate();

    if (offset.offsetType) {
      switch (offset.offsetType) {
        case "year":
          year = year + offset.amount;
          break;
        case "month":
          month = month + offset.amount;
          break;
        case "day":
          date = date + offset.amount;
          break;
        default:
          break;
      }
    }

    let formatDay = new Date(year, month, date, 0, 0, 0);

    if (typeString) {
      formatDay = formatDay.toDateString();
    }

    return formatDay;
  }
}

export default CustomUtil;

Edit1: My apologies for missing an important piece of information. I have set EVENTS_DRAFT.length = 0; in the turnCalculator.js I am calling. Perhaps this, along with different files referencing the same imported EVENTS_DRAFT object is causing this? Unfortunately, I can't use immutable as I intend this object to be shared.

turnCalculator.js

import { TASK_TEMPLATES } from "../fakeDb/task_templates";
import { EVENTS } from "../fakeDb/events";
import getDaysFromToday from "./getDaysFromToday";
import { EVENTS_DRAFT } from "../store/stateless/event_draft";
import CustomUtil from "./CustomUtil";

let tasked_dates_arr = [];
let merged_dates = [];

const turnCalculator = (templateId, calDate) => {
  tasked_dates_arr = [];
  merged_dates = [];

  const template = TASK_TEMPLATES.find((template) => {
    return template.id === templateId;
  });
  const first_date = EVENTS_DRAFT[0].duration[0];

  let next_60_days = new Date(calDate.getTime());
  next_60_days.setDate(calDate.getDate() + 60);

  const days_diff = dateDiffInDays(
    new Date(first_date),
    new Date(next_60_days)
  );
  const all_dates_arr = getDaysFromToday(days_diff, calDate);

  const assignees = template.assignees;

  tasked_dates_arr = all_dates_arr.filter((calDate) => {
    return getTaskedDates(calDate, template);
  });

  let i = 0;
  tasked_dates_arr.forEach((date_str) => {
    merged_dates.push({
      date: new Date(date_str),
      assignee: [assignees[i]],
    });

    if (i === assignees.length - 1) {
      i = 0;
    } else {
      i++;
    }
  });

  EVENTS_DRAFT.forEach((e_obj) => {
    if (!e_obj.assignees) {
      merged_dates.forEach((da_obj) => {
        if (da_obj.date.getTime() === new Date(e_obj.duration[0]).getTime()) {
          const obj_to_submit = { ...e_obj, assignees: da_obj.assignee };
          EVENTS.push(obj_to_submit);
        }
      });
    }
  });

  EVENTS_DRAFT.length = 0; //<==== Removing this also solves the issue, but I need this to reset the object back to empty [ ].
};

function dateDiffInDays(a, b) {
  const _MS_PER_DAY = 1000 * 60 * 60 * 24;
  const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
  const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());

  return Math.floor((utc2 - utc1) / _MS_PER_DAY);
}

/* mirros getCreateTasks */
const getTaskedDates = (calDate, template) => {
  let have_task_date;

  for (let i = 0; i < template.days.length; i++) {
    let unified_day = template.days[i];
    let cell_day;
    if (template.type === "monthly") {
      cell_day = calDate.getDate();
      if (template.days[i] === "month end") {
        unified_day = CustomUtil.getMonthLastDate(calDate);
      }
    } else {
      cell_day = calDate.getDay();
    }
    if (cell_day == unified_day) {
      have_task_date = CustomUtil.formatTimelessDate(
        calDate.toDateString(),
        true
      );
      break;
    }
  }

  if (have_task_date) {
    return have_task_date;
  }
};

export default turnCalculator;

Full source code can be found here: https://github.com/SeanLuo-FSWD/RTFEJS

Sean
  • 508
  • 6
  • 20
  • 2
    Is there an error message when you try to push with `duration`? – Sinan Yaman Oct 12 '21 at 05:53
  • 2
    Is there an error? Have you tried logging in your util function? – dork Oct 12 '21 at 05:56
  • 1
    this feels like a weird combo of point by value vs point by reference, and _something_ getting mutated... can you do `EVENTS_DRAFT = [...EVENTS_DRAFT, obj_submit];` to try and keep everything immutable? – John Hooper Oct 12 '21 at 06:09
  • @SinanYaman, unfortunately no error message shown. But I did add an edit at the bottom to include additional source code and some explanation. Thanks – Sean Oct 12 '21 at 16:22
  • @dork, I tried logging, everything seems fine and in order with no error message. I have made an edit to include additional info and the source code. hopefully this helps. – Sean Oct 12 '21 at 16:22
  • @JohnHooper, I think you are on the right path, as I have several files referring to EVENTS_DRAFT and making changes to it, notably having `EVENTS_DRAFT.length = 0;` in the turnCalculator.js as included in the additional edits at the bottom. But I cannot use immutable method as I want this object to be shared. Hopefully this helps as I am out of my wits. – Sean Oct 12 '21 at 16:25

1 Answers1

0

The issue was actually due to my misconception regarding the console.log, which keeps a live link to the array, not a snapshot. So there is nothing wrong with the array.

More detail here: console.log of element.children shows 0 length but has three entries when expanded later

Sean
  • 508
  • 6
  • 20