Tjoeaon
Tjoeaon

Reputation: 1523

How to check two objects for difference in values in JS?

I want to edit a existing user in Node. My front-end is in pug. My user table has lots of fields (about 20 to 25), and some have to be unique, like email and username, which I have functions to check if they are not a duplicate.

I only want to update values that has changed on the client, my edit form already has the values of the user of course.

I thought the best way to achieve this is to check all the inputs from req.body, and if it is different from any user values, I should update it. (Perhaps any different methods? Can't I check if the inputs are 'dirty'?)

This could be the situation. Note the req.body object, with values that my user table doesn't have, like password_confirm

req.body = { 
    username: 'test',
    email: '[email protected]', 
    password: '1234',
    password_confirm: '1234',
    location: 'New York',
    website: 'new-website.com',
    bio: undefined,
    expertise: 'New expertise'
}
user = { 
    username: 'test',
    email: '[email protected]', 
    password: '1234',
    location: 'San Fransico',
    website: 'website.com',
    bio: null,
    expertise: null
}

I now only want to update the changed location, website and expertise fields. I tried many things, using reduce and lodash, but I can't get the fields that I'm looking for.

NB I already checked different StackOverflow questions but nothing seems to work for my situation..

Upvotes: 1

Views: 86

Answers (4)

Tjoeaon
Tjoeaon

Reputation: 1523

I figured it out.

Based on @ponary-kostek & @anuragasaurus 's answer, this is what worked for me:

    const differences = {};
    Object.keys(req.body).forEach((key)=> {
        if(req.body[key].length == 0) req.body[key] = null;
        if(stakeholder.hasOwnProperty(key) && stakeholder[key]!=req.body[key]){
            differences[key] = req.body[key];
        }
    });

This returns an object with the changed keys and their values.

Because the fields from my user object are retrieved from a SQL DB, they are null. Also, empty body fields are not undefined, but strings. Meaning if the input is empty, it is an empty string, and to compare it to my user object it should first be null.

Thanks everyone for their answers.

Upvotes: 0

ponury-kostek
ponury-kostek

Reputation: 8060

If you need diff object use this:

function diff(oldObject, newObject) {
    const diff = {};
    Object.keys(oldObject).forEach((key) => {
        if (oldObject[key] != newObject[key] && newObject[key] !== undefined) {
            diff[key] = newObject[key];
        }
    });
    return diff;
}

var body = {
	username : 'test',
	email : '[email protected]',
	password : '1234',
	password_confirm : '1234',
	location : 'New York',
	website : 'new-website.com',
	bio : undefined,
	expertise : 'New expertise'
}
var user = {
	username : 'test',
	email : '[email protected]',
	password : '1234',
	location : 'San Fransico',
	website : 'website.com',
	bio : null,
	expertise : null
}
function diff(oldObject, newObject) {
	const diff = {};
	Object.keys(oldObject).forEach((key) => {
		if (oldObject[key] != newObject[key] && newObject[key] !== undefined) {
			diff[key] = newObject[key];
		}
	});
	return diff;
}
console.log(diff(user, body));

Upvotes: 1

Umair Sarfraz
Umair Sarfraz

Reputation: 5953

Well, I think you are over complicating. You don't even need lodash for this.

Object.assign({}, user, req.body);

would work, since you said yourself that you can have different fields in req.body.

Upvotes: 1

Anurag Awasthi
Anurag Awasthi

Reputation: 6233

From what I understood from your question, give this a try,

Object.keys(req.body).forEach((key)=>{
    if(user[key] && user[key]!=req.body[key]){
        user[key] = req.body[key];
    }
})

Upvotes: 2

Related Questions