Puzzling Issue while working with Date() in Ionic (RESOLVED)

I am struggling to get my head around the puzzling issue arising when setting and manipulating date and time.

Here is what I am doing:

I am creating an array repeated_pickups that stores pickup objects differing in date and time.
Each successive pickup object in array is containing a new date as a string but the same time, a string too. The new date is different from previous as it is set through number of days incremental using JS in-built Date().set() method.

Here is my code:

    let pickup = this.pickup.getPickupObject(); // pickup object { date: '', time: ''} imported from provider
    const time = this.showTime; // string containg current time in ''09:30 AM" format
    let repeated_pickups = [];
     
    //creating pickup object with same time and date incremented by 1 day for next five consecutive days
    for(var i = 0; i < 5; i++) {
            pickup.time = time; //setting time to pickup object

            let date: any = new Date(); // today's date
            date.setDate(date.getDate() + ( i + 1)); // adding (i + 1) days to today date

            let next_date = new Date(date).toISOString().split('T')[0]; // formatting the new date in form 'YYYY-mm-dd'

            pickup.date = next_date; // setting a date string in pickup object with new_date

            repeated_pickups.push(pickup);
          }

Now issue here is that instead of getting increasing dates in each pickup object in repeated_pickups array, I am getting last date created in all objects.

Further, during debugging in which I commented out the entire for loop and added pickup.time = time; after the following code:

    let pickup = this.pickup.getPickupObject(); // pickup object { date: '', time: ''} imported from provider
    const time = this.showTime; // string containg current time in ''09:30 AM" format
    let repeated_pickups = [];

I got pickup object containing some out-of-blue date string with time too, despite not setting it.

Even with for loop code added in debugging but this time placing pickup.time = time; back in its original position inside the loop, I got pickup object which should be empty before loop containing date and time values set inside loop.

I also noted that through console.log() that next_date increments to new date successfully. But it is just when assigning it to pickup.date that I get last incremented date in all objects inside repeated_pickups array.

Can someone please have a look at this and let me know where I am getting wrong.

I’ll greatly appreciate the help!

Move this line

let pickup = this.pickup.getPickupObject(); // pickup object { date: ‘’, time: ‘’} imported from provider

Inside your loop.

Thank you for your reply.

I tried what you said but am still getting same last date value in each object element inside an array. And the should-be empty array before loop is replaced by resultant array containing objects. :neutral_face:

Perhaps you shoud change

let repeated_pickups = [];

To

let repeated_pickups: Array<any>= [];

Or use the pickup type instead of any

Why aren’t you using some time/date lib like https://momentjs.com/ ? It makes things with dates so much easier.

1 Like

I would advice https://date-fns.org too, more lightweight than moment but maybe not yet have the calendar view (not sure).

One of the other, @waleedshkt I would advice to use one of these libs to manipulate dates, make these operations easier

1 Like

also I think I maybe kind of get your issue @waleedshkt

since you are doing

let pickup = this.pickup.getPickupObject();

and manipulating this without creating new object in your loops, you are maybe always modifying the same object (pointer reference?)

pickup.time = time;
pickup.date = next_date;

try following

const time = this.showTime; // string containg current time in ''09:30 AM" format
let repeated_pickups = new Array();
 
//creating pickup object with same time and date incremented by 1 day for next five consecutive days
for(var i = 0; i < 5; i++) {

        let date: any = new Date(); // today's date
        date.setDate(date.getDate() + ( i + 1)); // adding (i + 1) days to today date

        let next_date = new Date(date).toISOString().split('T')[0]; // formatting the new date in form 'YYYY-mm-dd'

         // here the tricks
        repeated_pickups.push({
            date: next_date,
            time: time
        });
      }
1 Like

Hi there,

It seems like this isn’t an issue due to date manipulation using Date() object. I used moment to do the same. But same issue is popping up in that case too.

It’s more related to object mutation. As I’m fairly new to playing with dates inside loops and assigning them to other pre-defined variables that I’m having a hard time debugging where is the fault.

Hi,

I tried your trick and it did somewhat put me on right course to resolve the issue.

So instead of importing an object model, I declared and initialized it inside for loop. But here it gets puzzling again: When assigning the new formatted date to next_date and setting it inside object in push(), I still get same repeated date values.

But when I tried directly setting new Date(date).toISOString().split('T')[0] to {date: ,...}, it worked! But then the supposed-to-be-empty repeated_pickups array declared and initialized likeany[] = [] gets populated with resulting object elements.

I don’t get this, sorry, I began to be lost a bit.

  1. Could you try to give an example of your goal?

like

Use enter : 27th September 2017at 5pm in this.pickup.getPickupObject()
Result of the loop: An array containing

28th September 2017at 5pm
29th September 2017at 5pm
30th September 2017at 5pm
1st Oktober 2017at 5pm
2nd Oktober 2017at 5pm

btw. just noticed with that example, not sure, but since you are just modifying the day, once 31 gonna be reach, the date gonna begin with 1 but with the same month no? maybe definitely good to add date-fns or momentjs to do the date manipulation

  1. Could you past an updated version of your code?
const time = this.showTime; // string containg time in ''09:30 AM" format that user selects
let repeated_pickups = new Array();
 
//creating pickup object with same time and date incremented by 1 day for next five consecutive days
for(var i = 0; i < 5; i++) {

        let date: any = new Date(); // today's date
        date.setDate(date.getDate() + ( i + 1)); // adding (i + 1) days to today date

        repeated_pickups.push({
            date:  new Date(date).toISOString().split('T')[0], // formatting the new date in form 'YYYY-mm-dd
            time: time
        });
      }

So user selects a date e.g 2018-01-27’ and time e.g 05:00 AM. Then above code generates an array of five objects (let say user wants a pickup to be repeated daily for the next five days).

So he/ she gets

[{date: '2018-01-28', time: '05:00 AM'}, 
{date: '2018-01-29', time: '05:00 AM'},
{date: '2018-01-30', time: '05:00 AM'},
{date: '2018-02-01', time: '05:00 AM'},        // let say a month of 30 days
{date: '2018-02-02', time: '05:00 AM'}]

And no, you don’t have to worry about when to jump to new month when current month ends as inside a loop a date.setDate(date.getDate() + ( i + 1)); is taking care of it above.

And the user selected date and time are contained in this.pickup.getPickupObject() right?

If so:

const time:string = this.showTime;
let repeated_pickups:any[] = new Array();

for(let i:number = 0; i < 5; i++) {

    let myDate: Date = new Date(this.pickup.getPickupObject().getTime());
    myDate.setDate(myDate.getDate() + i + 1);

    repeated_pickups.push({
        date:  myDate.toISOString().split('T')[0],
        time: time
    });
  }

No, the time selected is contained in variable this.showTime.

One thing I believe I should have clarified earlier is that in my example above user is assumed to select today’s date. Also that this.pickup and pickup object has nothing to do with one another. I may have made it it look confusing but both are as far related as by their similar names only. You can call pickup object, order object

One can generalize it for some other selected date in future simply by replacing above date with the following:

let date: any = new Date(this.userSelectedDate)

Then this with new Date();

const time: string = '5am';
let userDate: Date = new Date();

let repeated_pickups: any[] = new Array();

for (let i: number = 0; i < 5; i++) {

  let myDate: Date = new Date(userDate.getTime());
  myDate.setDate(myDate.getDate() + i + 1);

  repeated_pickups.push({
    date: myDate.toISOString().split('T')[0],
    time: time
  });

}

console.log(repeated_pickups);

Furthermore, tested this locally, worked as you expect.

So you let the user date remained outside the loop, and assigned it to new newly created Date variable inside loop. In this way, you worked with the same variable inside loop which is neater.

I, on the other hand, created a new Date instance with user-selected ‘modified-to-new-date’ date later in push(). Less clean! :grin:

Great!

that’s the key phrase. if I understand correctly the problem you were facing is that you were modifying always the same object. creating a new object solve it. not sure it’s really that, I just think in an object oriented way, did too much Java :wink:

Anyway I hope it is the result you were expecting, happy coding, have fun