2

If I know there's a property in common between two JavaScript objects called "req" and "updatedDoc" respectively, is there a way I can use a placeholder parameter to represent any key, so that I can find the right one that matches on the two objects? I tried this but it doesn't work:

for (const [key, val] of Object.entries(req)) {
  if (key === updatedDoc[key]) {
    console.log("key, val", key, val);
  }
}

By the way, in my use case I know there will always be one matching property between the two objects. And to clarify, the two objects are called "req" and "updatedDoc". I don't know what they key will be, but I know the two objects will have one key in common.

To add a little more clarity, "req" is going to be something simple, like:

const req = { 
  "deleted" : true, 
  "apiKey" : "4d9d9291", 
  "token" : "ffdsfjsdfsdjfa" 
}

... whereas updatedDoc will be a full document, like this:

const updatedDoc = {
   _id: <ObjectId>,
   firstName: "John",
   lastName: "Smith",
   age: 42
   deleted: false
}

Both have a property called "deleted". Basically I'm matching a request passed in with the whole document it pertains to. I then want to take in the value from "req" and save it to "updatedDoc" for the correct key. But first I need to find the matching key, and pull out the value from "req". Is there a way I can do this?

Muirik
  • 6,049
  • 7
  • 58
  • 116
  • Is updatedDoc is an object of objects ? – Osama Feb 22 '19 at 20:49
  • Are you only testing for a property AND value that matches? or just the keys. If just the keys, any of these would work: https://stackoverflow.com/questions/12433604/how-can-i-find-matching-values-in-two-arrays to get you the matches, which you can then use to get the values etc. – Kevin B Feb 22 '19 at 20:50
  • Added more clarity above. – Muirik Feb 22 '19 at 20:52
  • yeah, so just grab the keys of each and do a diff. If you know the one object will only have one key, it becomes even simpler; no need to loop. – Kevin B Feb 22 '19 at 20:53
  • key === updatedDoc[key] I think the problem here is that by this way you compare the key from req with the value from updatedDoc , while you want to compare the key of these two objects – Osama Feb 22 '19 at 20:53
  • @Kevin, `req` may have more than one key/value pair, because there's also an `apiKey` and `token` that comes with the request. But only one key will match to a key from `updatedDoc`. – Muirik Feb 22 '19 at 20:56
  • You could try `if(key in updatedDoc)` rather than `if(key === updatedDoc[key])` – Khauri Feb 22 '19 at 21:04
  • @Khauri, that will return all the key/values, rather than just the one in common. – Muirik Feb 22 '19 at 21:11
  • So you also want the values of matching keys to be equal? If so you might do `if(key in updatedDoc && val === updatedDoc[key])` or even just `if(val === updatedDoc[key])`? – Khauri Feb 22 '19 at 21:15
  • No, I just want to know what the value passed in to `req` is for that matching key. In other words, I want a result like: `{ "deleted" : true }`. This pulls out the matching key, and tells what the value was for that key in `req`. – Muirik Feb 22 '19 at 21:16
  • Okay, perhaps your question is a little confusing to me. If it's not too much trouble, do you think you could update your question with example input for req and updatedDoc and an example of the required result/output? – Khauri Feb 22 '19 at 21:19
  • Seems that what you're looking for is `Object.assign()`, but you'll need to delete `apiKey` and `token` from `req` before merging the objects. – Alexey Lebedev Feb 22 '19 at 21:22
  • @Alexey, my goal is to effectively do the cleanup by only pulling out the matching key/value pair, then I can just save that one property to the document. – Muirik Feb 22 '19 at 21:29

3 Answers3

2

You should be able to just modify your loop to change

if (key === updatedDoc[key]) to if (key in updatedDoc)

Everything inside this if statement will only be performed on keys that exist both in req and updatedDoc. The value stored for the key in req will be val, which was dereferenced from Object.entries

You can change updatedData to the new value like so updatedData[key] = val. You can also store the change in an array for later, if you like.

const updatedDoc = {
  firstName: "John",
  lastName: "Smith",
  age: 42,
  deleted: false
}
const req = {
  "deleted": true,
  "apiKey": "4d9d9291",
  "token": "ffdsfjsdfsdjfa"
}

const changes = []

for (const [key, val] of Object.entries(req)) {
  if (key in updatedDoc) {
    // get the previous value
    const oldVal = updatedDoc[key]
    // update updatedDoc
    updatedDoc[key] = val
    // store the change or do whatever
    changes.push({
      [key]: {
        new: val,
        old: oldVal
      }
    })
  }
}

console.log(updatedDoc)

console.log(changes)
Khauri
  • 3,753
  • 1
  • 11
  • 19
1

Why not take a Set for the first object and filter the keys for the second object.

The result is an array with common keys.

var objectA = { a: 1, b: 2, c: 3 },
    objectB = { b: 4, c: 5, d: 6 },
    common = Object.keys(objectB).filter(Set.prototype.has, new Set(Object.keys(objectA))),
    values = common.map(k => objectA[k]);

console.log(common);
console.log(values);

A bit shorter version.

var objectA = { a: 1, b: 2, c: 3 },
    objectB = { b: 4, c: 5, d: 6 },
    common = Object.keys(objectA).filter({}.hasOwnProperty.bind(objectB)),
    values = common.map(k => objectA[k]);

console.log(common);
console.log(values);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • So this gives me the keys in common, which is good, but I'd also need to know the value for that matching key found in req. So, in your case here: `[ { "b" : 4 }, { "c" : 5} ]`, assuming `objectB` represents `req`. – Muirik Feb 22 '19 at 21:18
  • you could map the values, please see edit. do you want an object with common key and values form objectA? – Nina Scholz Feb 22 '19 at 21:27
  • Nice JavaScript Jiu Jitsu here. I think this will work, thanks. – Muirik Feb 22 '19 at 21:31
0

Try this solution I think it will solve the problem

updatedDoc.forEach(function(i,v){
for (const [key, val] of Object.entries(req)) {
      if (key === i && req[key]==updatedDoc[i]) {
            console.log("key, val", key, val);
      }
});
Muirik
  • 6,049
  • 7
  • 58
  • 116
Osama
  • 2,912
  • 1
  • 12
  • 15