-1

I want to create object like this

var items = [{'2021-07-06':[{todo:'Hello'},{todo:'World'}]}]

Here the date should be dynamic so I tried to push value to it like this but this doesn't work

{...items, [CurrentDate] : {...[CurrentDate], todo:'I am here'}}

[CurrentDate] refers to the current date here which is '2021-07-06' and push new todo in array. Also if the date key not present then I want to add new Date eg if '2021-07-08' is not present then add to object and add new todo to it.

RobG
  • 142,382
  • 31
  • 172
  • 209
Aariana
  • 39
  • 6
  • *items* is an array, but in the "like this" code it's spread to an object. `{...[CurrentDate}}` is going to spread a string like '2021-07-06' to an object like `{"0": "2", "1": "0", "2": "2", "3": "1", "4": "-", ...}`, i.e. with property names from the indexes and values from the characters. Perhaps you mean to do `[{[CurrentDate] : [...items, {todo:'I am here'}]}]` or similar. – RobG Jul 06 '21 at 04:06
  • yes @RobG correct it is updating items array like this, any idea or solution for it. – Aariana Jul 06 '21 at 04:09

2 Answers2

1

You first have to find the right element in items to update (e.g. using findIndex), then access it by index. Then you can update that object using spread syntax.

However, spread is an inefficient approach as it creates a duplicate object for no reason. Likely push is much more efficient (and semantic) as it just adds an element to the array.

The following also handles the case where currentDate doesn't exist in the items array.

let items = [{'2021-07-06': [{todo: 'Hello'}, {todo: 'World'}]}];

function updateItems(items, key, newItem) {
  // Find the right object in items
  let idx = items.findIndex(obj => obj.hasOwnProperty(key));

  // If not found, append a new object
  if (idx == -1) {
    items = [...items, {[key]: newItem}];

  // Otherwise, update existing object
  } else {
    items[idx] = {
      [key]: [...items[idx][key], newItem]
    };
  }
  // Unnecessary but handy
  return items;
}

// Update existing object
updateItems(items, '2021-07-06', {todo: 'new item'});
console.log('Update existing item\n' + JSON.stringify(items));

// Add new object
// If using spread, must keep new array returned by updateItems
items = updateItems(items, '2021-07-07', {todo: 'new key and item'});
console.log('Add new item\n' + JSON.stringify(items));

Spread also creates a shallow copy, whereas push doesn't affect any existing elements in the array and is less code to type.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • thanks for the answer but can it create new sub object with the date if it is not present like '2021-07-08' is not present can it create '2021-07-08' : [{todo : 'here'}] like this object – Aariana Jul 06 '21 at 05:48
  • Yes, just test the value of *idx* and if it's -1, then push a new object like `items.push({[currentDate]: [/* items objects */] })`. – RobG Jul 06 '21 at 06:04
  • thanks @RobG I will try it and will let you know – Aariana Jul 06 '21 at 06:18
  • one object gets added but when I try to add another object on same or different date I get items.findIndex is not a function – Aariana Jul 06 '21 at 07:14
  • @Aariana—just noticed that. It's because *spread* copies the array so the global *items* references the un–updated array. I needed to assign the returned array to *items*, see updated post. It all depends on whether you think *updateItems* should mutate the passed in array, or create a copy (noting that the copy still references the original array's elements). – RobG Jul 06 '21 at 09:01
0

it is easy.


var items = [
   {
      '2021-07-06':[
         {todo:'Hello1'},{todo:'World1'},
         {todo:'Hello2'},{todo:'World2'},
         {todo:'Hello3'},{todo:'World3'},
         {todo:'Hello4'},{todo:'World4'},
       ],
      '2021-07-07':[
         {todo:'Hello11'},{todo:'World11'},
         {todo:'Hello22'},{todo:'World22'},
         {todo:'Hello33'},{todo:'World33'},
         {todo:'Hello44'},{todo:'World44'},
       ]
    }
];

let's imagine we want to add

'2021-07-08':[
         {todo:'Hello111'},{todo:'World111'},
         {todo:'Hello222'},{todo:'World222'},
         {todo:'Hello333'},{todo:'World333'},
         {todo:'Hello444'},{todo:'World444'},
       ]

the way we would do so is like this


 const newItem = '2021-07-08':[
         {todo:'Hello111'},{todo:'World111'},
         {todo:'Hello222'},{todo:'World222'},
         {todo:'Hello333'},{todo:'World333'},
         {todo:'Hello444'},{todo:'World444'},
       ];

const newTodo = {todo:"Hello5"};
///....

items = [...items, newItem];

/**
* IF YOU WANT TO ADD AN OBJ TO A DATE, DO IT LIKE THIS
*/

items[0]=[...items[0], newTodo];

items is an array, so you need to loop'em items to find the correct index


for (let i=0; i < items.length; i++) {
  // before doing the next step validate if the items at position i is equals to an array
  
   const currentItem = [...items[i]];

  if (currentItem.anythingYouThinkWouldBeCondition === true) {
     currentItem.push(newTodo);
    items = [...items,currentItem];

   break;

  }


}


Ernesto
  • 3,944
  • 1
  • 14
  • 29