0

I have array of JavaScript object elements inside. Here is example:

var contacts =[{"id":1,"first":"Mike","last":"Johnson","email":"mjohnson@gmail.com","phone":"(203) 567-9055","status":1},{"id":2,"first":"John","last":"Dunn","email":"jdunn@gmail.com","phone":"(319) 451-7889","status":1},{"id":3,"first":"Lisa","last":"Morgan","email":"lmorgan@gmail.com","phone":"(508) 233-8908","status":1},{"id":4,"first":"Dave","last":"Hart","email":"dhart@gmail.com","phone":"(509) 874-9411","status":1}];

I have to insert/update records in that array. I'm not sure what would be the best approach to check if record exist in that array. If exist then update js object, if not generate new id. Ideally that id would be an integer and starts after the highest current id in js object. So in data above the highest id value is 4. If I insert new record id for the new record should be 5. Is there a good way to achieve that with JavaScript?

function saveContact(){
    var frmObject = $(this),
        frmKey = $("#frm_id").val(),
        formData = frmObject.serialize(),
        contactRecord = contacts.find(item => item.id === Number(frmKey));;

        if (contactRecord) {
            contacts[frmKey] = getJSON(frmObject.serializeArray()); // If already exist in array then update object
        }else{
            frmKey = 'generate new id';
            contacts[frmKey] = getJSON(frmObject.serializeArray()); // If doesn't exist generate new key and insert object in array 
        }
}
espresso_coffee
  • 5,980
  • 11
  • 83
  • 193
  • It looks as if your code would be a lot easier to work with if you were able to use an object of objects (indexed by ID) instead of an array of objects - is that an option? Using `.find` every time doesn't seem like the best idea. (Doesn't *really* matter, but code would be cleaner) – CertainPerformance Aug 02 '18 at 01:47
  • @CertainPerformance Object of objects is an option, so if you can provide an example with how to generate `id` that is the most important part for me. – espresso_coffee Aug 02 '18 at 01:49

5 Answers5

2

This was mentioned in a comment, but I'll flesh it out a bit.

If your data is an object keyed to ID instead of an array, it will force IDs to be unique, since objects must have unique keys.

For example:

var contacts =[{"id":1,"first":"Mike","last":"Johnson","email":"mjohnson@gmail.com","phone":"(203) 567-9055","status":1},{"id":2,"first":"John","last":"Dunn","email":"jdunn@gmail.com","phone":"(319) 451-7889","status":1},{"id":3,"first":"Lisa","last":"Morgan","email":"lmorgan@gmail.com","phone":"(508) 233-8908","status":1},{"id":4,"first":"Dave","last":"Hart","email":"dhart@gmail.com","phone":"(509) 874-9411","status":1}];

// just a quick dirty conversion
let obj = contacts.reduce((a, c) => (a[c.id] = c, a), {})

//Object looks like:
console.log(obj)

// find the largest key // maybe a good way to decide the next key
largest_id = Math.max(...Object.keys(obj))
console.log("largest ID", largest_id)

// is ID 4 taken?
console.log("is there a 4", 4 in obj) //yes
// alternatively obj.hasOwnProperty('4')

// is 5?
console.log("is there a 5", 5 in obj) //no

// update ID 4:
obj['4'].first = "Mark"
console.log(obj['4'])

Hopefully that is a little bit of an incentive to try this approach instead of an array.

Mark
  • 90,562
  • 7
  • 108
  • 148
  • I have tried your proposed solution using `Math.max(Object.keys(obj))` but that returned `NaN` instead I used this code `Object.keys(obj).reduce((a, b) => obj[a] > obj[b] ? a : b);` and that returned `4`. Do you have any opinion on using `reduce()` method for this purpose? – espresso_coffee Aug 02 '18 at 02:13
  • I think reduce is fine, but its purpose is a little less obvious visually. It looks like your `Math.max` is missing the spread `...` operator. – Mark Aug 02 '18 at 02:14
  • `...` that is required ? I thought it was just a comment. Never seen that before. – espresso_coffee Aug 02 '18 at 02:15
  • @espresso_coffee Yes, to use `Math.max` like this you need it. It spreads the array out into individual values turning something like `Math.max( [1, 2, 3] )` into `Math.max( 1, 2, 3 )` – Mark Aug 02 '18 at 02:17
  • 1
    Very interesting, I just tested and works fine. Also that will return `number` type vs my solution using `reduce` returns `string` type. Thanks for your help. – espresso_coffee Aug 02 '18 at 02:19
1

Find the last object in the array and get it's id:

contacts[contacts.length-1].id

Then simply add 1 and you have the next id number.

dandeto
  • 756
  • 6
  • 13
  • In case if I decide to use object of objects what would be solution in that case? I can't use `.length` on objects so is there any other way to find the length of an object? – espresso_coffee Aug 02 '18 at 02:01
  • You can get the last key, but that depends on how you structure the object. Give this a read: https://stackoverflow.com/questions/4317456/getting-the-last-item-in-a-javascript-object If you could give me an example of how the object would look I'd be happy to give you more guidance! – dandeto Aug 02 '18 at 02:06
  • 1
    I found this approach and seems to work just fine `var test = Object.keys(contacts).reduce((a, b) => contacts[a] > contacts[b] ? a : b);` returns highest key value. So I just add `+1` to generate new key for my object. Thanks for your help! – espresso_coffee Aug 02 '18 at 02:07
0

You can use an Object to store your Collection of Objects. Each time an object is injected in the collection, a new id is generated (based on the length of the collection), if the id of the object inserted in the collection, already exists, it only performs an update.

const collection = {};

function insert(obj){
   // if id is set in object and object is already in Collection... 
   if(obj.id && collection.hasOwnProperty(obj.id) ){ 
     // Update object!
     collection[obj.id]= Object.assign(collection[ obj.id], obj) ;
   }else{ 
     // if provided object has no ID... generate it!
     if( !obj.id ) obj.id = Object.keys(collection).length;
     // insert provided object to collection;
     collection[obj.id]= obj;
   }
   // return generaed id;
   return obj.id;
}


// Let's test...

let obj_1 ={"first":"Mike","last":"Johnson","email":"mjohnson@gmail.com","phone":"(203) 567-9055","status":1};

let obj_2 = {"first":"John","last":"Dunn","email":"jdunn@gmail.com","phone":"(319) 451-7889","status":1};

// insert bth object
insert(obj_1);
insert(obj_2);
// perform a change in object 2
obj_2.first ='Joseph';
// insert object 2 again...
insert(obj_2);
// object 2 has been updated, and all have unique ids
console.log(collection);
colxi
  • 7,640
  • 2
  • 45
  • 43
  • 1
    Sure, but how do you tell if the set has `id:1`. It seems unlikely that you will have a reference to the exact object when you want to update it. – Mark Aug 02 '18 at 01:56
  • sorry i misunderstood your question. i updated my answer, with a better approach – colxi Aug 02 '18 at 02:19
0

You can create a global variable and use it as a counter, every time for new record you can increase it by one, for existing just update.

You can store all json in database, at the time of fetch just take count of array elements/last element's Id and set it in counter.

Also if you do not need auto generated id in sequence you can also use random function to generate unique id everytime.

0

You can achieve this in simple way if you manage your data as Object of objects.

var contacts  = {

   
  1: {
    first: "Mike",
    last: "Johnson",    
    email:"mjohnson@gmail.com",
    phone:"(203) 567-9055",
    status:"1"
 },
  2: {
    first: "John",
    last: "Dunn",    
    email:"jdunn@gmail.com",
    phone:"(319) 451-7889",
    status:"1"
 },
  3: {
    first: "Lisa",
    last: "Morgan",    
    email:"lmorgan@gmail.com",
    phone:"(508) 233-8908",
    status:"1"
 },
  4: {
    first: "Dave",
    last: "Hart",    
    email:"dhart@gmail.com",
    phone:"(509) 874-9411",
    status:"1"
 }
};

var frmKey = 5;
if(contacts[frmKey]){
console.log(contacts[frmKey]);
 // If already exist in array then update object
}else{
  contacts[frmKey] = {first: "Lisa1",last: "Morgan1", email:"lmorgan1@gmail.com", phone:"(508) 233-8908", status:"1" };

  console.log("Added New Key::"+frmKey,contacts[frmKey]);

}
NullPointer
  • 7,094
  • 5
  • 27
  • 41