189

I have an object that holds alerts and some information about them:

var alerts = { 
    1: { app: 'helloworld', message: 'message' },
    2: { app: 'helloagain', message: 'another message' }
}

In addition to this, I have a variable that says how many alerts there are, alertNo. My question is, when I go to add a new alert, is there a way to append the alert onto the alerts object?

Matt
  • 3,682
  • 1
  • 21
  • 27
Steve Gattuso
  • 7,644
  • 10
  • 44
  • 59
  • 6
    I think you have a problem with your posted json: 1:{app:'helloworld','message'} => 1:{app:'helloworld',message : 'a message'} ? – Andreas Grech Mar 05 '09 at 22:49

13 Answers13

248

How about storing the alerts as records in an array instead of properties of a single object ?

var alerts = [ 
    {num : 1, app:'helloworld',message:'message'},
    {num : 2, app:'helloagain',message:'another message'} 
]

And then to add one, just use push:

alerts.push({num : 3, app:'helloagain_again',message:'yet another message'});
greg121
  • 914
  • 1
  • 11
  • 19
Andreas Grech
  • 105,982
  • 98
  • 297
  • 360
  • 2
    This answer expects you to know the id of the alert to be added. Well, if you already know that, then you can simply follow the original object format and do: `alerts[3] = { app: 'hello3', message: 'message 3' }`. With this you can access a message by id: `alerts[2] => { app: 'helloworld', message: 'message' }`. Getting the length is then just: `Object.keys(alerts).length` (that bit *is* easier with arrays) – Matt Oct 13 '18 at 10:56
71

You can do this with Object.assign(). Sometimes you need an array, but when working with functions that expect a single JSON object -- such as an OData call -- I've found this method simpler than creating an array only to unpack it.

var alerts = { 
    1: {app:'helloworld',message:'message'},
    2: {app:'helloagain',message:'another message'}
}

alerts = Object.assign({3: {app:'helloagain_again',message:'yet another message'}}, alerts)

//Result:
console.log(alerts)
{ 
    1: {app:'helloworld',message:'message'},
    2: {app:'helloagain',message:'another message'}
    3: {app: "helloagain_again",message: "yet another message"}
} 

EDIT: To address the comment regarding getting the next key, you can get an array of the keys with the Object.keys() function -- see Vadi's answer for an example of incrementing the key. Similarly, you can get all the values with Object.values() and key-values pairs with Object.entries().

var alerts = { 
    1: {app:'helloworld',message:'message'},
    2: {app:'helloagain',message:'another message'}
}
console.log(Object.keys(alerts))
// Output
Array [ "1", "2" ]
Thane Plummer
  • 7,966
  • 3
  • 26
  • 30
  • 16
    This is actually the correct answer as the others are referring to transforming object into the array, but this way you are keeping it as the object. In the case of the author, its possible that it was better for him to work with the arrays, but this would be the answer on how to append to an object. – Goran Jakovljevic Sep 06 '18 at 10:08
  • 2
    yeah I agree ..In question there is not an array of object its just an object so this is the perfect answer ! – Kishan Oza Nov 23 '18 at 10:26
  • This is the proper answer though; how can you know which index you are going to add new object ? – Capan Mar 15 '19 at 08:41
  • 3
    this is the answer to the title question. – FistOfFury Aug 23 '19 at 19:37
61

jQuery $.extend(obj1, obj2) would merge 2 objects for you, but you should really be using an array.

var alertsObj = {
    1: {app:'helloworld','message'},
    2: {app:'helloagain',message:'another message'}
};

var alertArr = [
    {app:'helloworld','message'},
    {app:'helloagain',message:'another message'}
];

var newAlert = {app:'new',message:'message'};

$.extend(alertsObj, newAlert);
alertArr.push(newAlert);
respectTheCode
  • 42,348
  • 18
  • 73
  • 86
  • 1
    JQuery's extend is slow: http://trevmex.com/post/2531629773/jquerys-extend-is-slow. Also, there is a typo. $.extends() should read $.extend(). – ken Apr 04 '11 at 18:59
  • Good catch with the typo. There are situations where $.extends is helpful but you are right that it should be avoided when possible. – respectTheCode Apr 05 '11 at 14:47
  • 1
    I think extend() is ok when you only have a one record structure, without the brackets, for the rest I agree with respectTheCode, just use push() – elvenbyte Feb 06 '12 at 10:56
33

You can use spread syntax as follows..

var alerts = { 
1: { app: 'helloworld', message: 'message' },
2: { app: 'helloagain', message: 'another message' }
 }

alerts = {...alerts, 3: {app: 'hey there', message: 'another message'} }
hamdi islam
  • 1,327
  • 14
  • 26
21

Now with ES6 we have a very powerful spread operator (...Object) which can make this job very easy. It can be done as follows:

let alerts = {
  1: {
    app: 'helloworld',
    message: 'message'
  },
  2: {
    app: 'helloagain',
    message: 'another message'
  }
}
console.log("----------------before----------------");
console.log(alerts);
//now suppose you want to add another key called alertNo. with value 2 in the alerts object. 

alerts = {
  ...alerts,
  alertNo: 2
}

console.log("----------------After----------------");
console.log(alerts);
.as-console-wrapper {
  max-height: 100%!important;
}

Thats it. It will add the key you want. Hope this helps!!

Nexo
  • 2,125
  • 2
  • 10
  • 20
Harshit Agarwal
  • 2,308
  • 2
  • 15
  • 23
15

Like other answers pointed out, you might find it easier to work with an array.

If not:

var alerts = { 
    1: {app:'helloworld',message:'message'},
    2: {app:'helloagain',message:'another message'}
}

// Get the current size of the object
size = Object.keys(alerts).length

//add a new alert 
alerts[size + 1] = {app:'Your new app', message:'your new message'}

//Result:
console.log(alerts)
{ 
    1: {app:'helloworld',message:'message'},
    2: {app:'helloagain',message:'another message'}
    3: {app: "Another hello",message: "Another message"}
}      

try it:

https://jsbin.com/yogimo/edit?js,console

M.C
  • 359
  • 4
  • 7
  • This won't work, if you have deleted alerts or skipped a key. You should add something along the lines of `while(alerts[size]) size++;` And probably rename `size` to `newId`. – Till Mar 12 '19 at 08:34
10

You should really go with the array of alerts suggestions, but otherwise adding to the object you mentioned would look like this:

alerts[3]={"app":"goodbyeworld","message":"cya"};

But since you shouldn't use literal numbers as names quote everything and go with

alerts['3']={"app":"goodbyeworld","message":"cya"};

or you can make it an array of objects.

Accessing it looks like

alerts['1'].app
=> "helloworld"
dlamblin
  • 43,965
  • 20
  • 101
  • 140
5

Do you have the ability to change the outer-most structure to an array? So it would look like this

var alerts = [{"app":"helloworld","message":null},{"app":"helloagain","message":"another message"}];

So when you needed to add one, you can just push it onto the array

alerts.push( {"app":"goodbyeworld","message":"cya"} );

Then you have a built-in zero-based index for how the errors are enumerated.

Peter Bailey
  • 105,256
  • 31
  • 182
  • 206
3

Way easier with ES6:

let exampleObj = {
  arg1: {
    subArg1: 1,
    subArg2: 2,
  },
  arg2: {
    subArg1: 1,
    subArg2: 2,
  }
};

exampleObj.arg3 = {
  subArg1: 1,
  subArg2: 2,
};

console.log(exampleObj);
{
arg1: {subArg1: 1, subArg2: 2}
arg2: {subArg1: 1, subArg2: 2}
arg3: {subArg1: 1, subArg2: 2}
}
Maroun Melhem
  • 3,100
  • 1
  • 20
  • 22
1

I'm sorry but i can't comment your answers already due my reputation!...so, if you wanna modify the structure of your object, you must do like Thane Plummer says, but a little trick if you do not care where to put the item: it will be inserted on first position if you don't specify the number for the insertion.

This is wonderful if you want to pass a Json object for instance to a mongoDB function call and insert a new key inside the conditions you receive. In this case I gonna insert a item myUid with some info from a variable inside my code:

// From backend or anywhere
let myUid = { _id: 'userid128344'};
// ..
// ..

  let myrequest = { _id: '5d8c94a9f629620ea54ccaea'};
  const answer = findWithUid( myrequest).exec();

// ..
// ..

function findWithUid( conditions) {
  const cond_uid = Object.assign({uid: myUid}, conditions);
  // the object cond_uid now is:
  // {uid: 'userid128344', _id: '5d8c94a9f629620ea54ccaea'}
  // so you can pass the new object Json completly with the new key
  return myModel.find(cond_uid).exec();
}
Marc
  • 289
  • 2
  • 5
0

As an alternative, in ES6, spread syntax might be used. ${Object.keys(alerts).length + 1} returns next id for alert.

let alerts = { 
    1: {app:'helloworld',message:'message'},
    2: {app:'helloagain',message:'another message'}
};

alerts = {
  ...alerts, 
  [`${Object.keys(alerts).length + 1}`]: 
  { 
    app: `helloagain${Object.keys(alerts).length + 1}`,message: 'next message' 
  } 
};

console.log(alerts);
Vadi
  • 3,279
  • 2
  • 13
  • 30
0

[Javascript] After a bit of jiggery pokery, this worked for me:

 let dateEvents = (
            {
                'Count': 2,
                'Items': [
                    {
                        'LastPostedDateTime': {
                            "S": "10/16/2019 11:04:59"
                        }
                    },
                    {
                        'LastPostedDateTime': {
                            "S": "10/30/2019 21:41:39"
                        }
                    }
                ],
            }
        );
        console.log('dateEvents', dateEvents);

The problem I needed to solve was that I might have any number of events and they would all have the same name: LastPostedDateTime all that is different is the date and time.

David White
  • 621
  • 1
  • 10
  • 23
-1

Try this:

alerts.splice(0,0,{"app":"goodbyeworld","message":"cya"});

Works pretty well, it'll add it to the start of the array.

HM2K
  • 1,461
  • 4
  • 16
  • 21