1

I have an object. I want to check if a specific property exists in it or not.

The issue is: the property that I am looking for, could be anywhere, i.e: the structure of the object is undefiend.

ex:

obj1 = { "propIWant": "xyz" }
obj2 = { "prop1": [ {"key": "value"}, {"key":"value"}, 1, {"key": { "propIWant": "xyz"}}]

I've tried the following, but it seems to fail:

var lastTry = function(entry){
  // if entry is an array
  if(typeof entry === 'object' && entry instanceof Array){
    for(var i in entry)
      entry[i] = this.lastTry(entry[i]);
  }
  // if entry is a normal object
  else if(typeof entry === 'object'){
    // iterate through the properties of the entry
    for(var key in entry){
      console.log('key is: ', entry[key])
      // in case the entry itself is an array
      if(typeof entry[key] === 'object' && entry[key] instanceof Array){
        for(var i in entry[key]){
          entry[key][i] = this.lastTry(entry[key][i]);
        }
      }
      // in case the entry is a simple object
      else if(typeof entry[key] === 'object') {
        console.log('entry[key] is an object', entry[key], key)
        // if we directely find the property.. modify it
        if(entry[key].hasOwnProperty('_internal_url')){
          **entry[key]['_internal_url'] = "http://localhost:4000"+entry[key]['_internal_url'];** <-- My objective
        }
        else{
          // call this method again on that part
          // for(var i in entry[key]){
          //   if(typeof entry[key][i] === 'object')
          //     entry[key][i] = this.lastTry(entry[key][i]);
          // }
        }
      }else{
        console.log('not found')
      }
    }
  }
}

Can someone please help me out with it?I found the following: Find by key deep in a nested object but, instead of returning the found part, I want to edit the property and return the entire object with the modified property, not just the subset of the object that has that property.

Community
  • 1
  • 1

4 Answers4

0

Have you tried :

obj1.hasOwnProperty('propIWant')
Lucarob
  • 66
  • 4
0

If you wish to just check if property exists or not, you can stringify the object and then check if value exists in string or not.

var obj2 = {
  "prop1": [{
      "key": "value"
    }, {
      "key": "value"
    },
    1, {
      "key": {
        "propIWant": "xyz"
      }
    }
  ]
}

var key = 'propIWant';
var key2 = 'propIWant1';

function isPropInObject(obj, prop) {
  var r = new RegExp(prop + "\":")
  var match = JSON.stringify(obj).match(r);
  return match && match.length > 0 ? true : false
}

console.log(isPropInObject(obj2, key))
console.log(isPropInObject(obj2, key2))
Rajesh
  • 24,354
  • 5
  • 48
  • 79
  • The above could generate a problem: in case the object is the value of a collection of HTML element outputs ( let's say, the text field has something that matches what I am looking for, thus I may end up manipulating it as well). Nice idea, but in this case, it may not work as intended – Ramanathan Iyer Jul 15 '16 at 10:49
  • after due consideration, I applied stringifying the data and searching. The object property deep search returns the object that has the property i.e. I cannot change the property of the object I was looking for. Thanks for your help :) – Ramanathan Iyer Jul 18 '16 at 04:57
  • @RamanathanIyer I have already mentioned in my answer, **if you just wish to check**. If you wish to update, you can combine looping and my algo. This will help to avoid unnecessary check for invalid branches in tree – Rajesh Jul 18 '16 at 06:25
0

Well, check if the props is objects themselves and use a recursive function to find the "deep" property you are looking for?

function findProp(obj, lookFor) {
  for (var prop in obj) {
    if (prop == lookFor) return obj[prop]
    if (typeof obj[prop] == 'object') {
      var checkNested = findProp(obj[prop], lookFor)    
      if (checkNested) return checkNested
    }
  }
  return false
}

It works with console.log(findProp(obj2, 'propIWant'))

demo -> http://jsfiddle.net/zqcurg70/

davidkonrad
  • 83,997
  • 17
  • 205
  • 265
  • Thanks! Is it possible to manipulate the property and return the entire object? It keeps returning the searched value. My idea is to change its property. thanks again :) – Ramanathan Iyer Jul 15 '16 at 11:08
  • @RamanathanIyer, If I understand what you mean, then you could return an object like this updated fiddle -> **http://jsfiddle.net/2cab85L3/** – davidkonrad Jul 15 '16 at 11:16
  • 1
    @davidkonrad Just a small pointer, instead of `return false` as default value, do not return anything or `return undefined`. `false` can be a valid value. – Rajesh Jul 15 '16 at 11:20
  • @Rejesh, that is a good point! It really should return nothing or undefined. I'll correct it if the object addition is OK and it makes sense to improve the answer. – davidkonrad Jul 15 '16 at 11:25
  • Very nice solution! I've modified it for anyone interested in getting *all* the matching properties assuming there's more than one in the object. http://jsfiddle.net/7vpc06jb/ – Trevor Tiernan Mar 31 '23 at 22:59
0

Arrays and objects data can be access in a common way:

obj[key] and arr[pos];

This way you can simplify your code. Please note that key can be a string in case of a object or a number in case of an array.

The version below only searches in the element and eventual children elements(both arrays and objects) in a depth-first logic.

var found = 0;
var findProp = function(entry) {

  if(typeof entry === 'object')

    for(var key in entry) {

      findProp(entry[key]);

      if( entry[key].hasOwnProperty('_internal_url')) {
        found++;
        entry[key]['_internal_url'] = "http://localhost:4000" + entry[key]['_internal_url'];
      }
    }
}

console.log('found ' + found + 'occurrences');
morels
  • 2,095
  • 17
  • 24