2

Consider the object:

{
  "status": {
    "affects": {
      "date_of_death": "date_of_death",
      "cause_of_death": {
        "affects": {
          "other_cause_of_death": "other_cause_of_death"
        },
        "value": "Other"
      }
    },
    "value": "Deceased"
  }
}

What I want to do is loop over this and add {hide: true}. But there are some rules:

  • If the key does not have object as a value, take the value and make it into {hide: true}
  • If it has affects, like cause of death does, add hide: true after value.

So the resulting object should be:

{
  "status": {
    "affects": {
      "date_of_death": {hide: true},
      "cause_of_death": {
        "affects": {
          "other_cause_of_death": {hide: true}
        },
        "value": "Other",
        "hide": true,
      }
    },
    "value": "Deceased"
  }
}

now this might seem easy, until you get something like this:

{
  "comorbidities": [
    {
      "affects": {
        "malignancy_type": {
          "affects": {
            "malignancy_type_other": "malignancy_type_other"
          },
          "value": "Other"
        }
      },
      "value": "malignancy"
    },
    {
      "affects": {
        "heritable_syndrome_type": "heritable_syndrome_type"
      },
      "value": "heritable syndrome"
    }
  ]
}

The exact same thing should happen here. Accept notice how its an array, This should do it recursively, deep diving into the affects, until no more can be found.

I have gotten this far:

export const createHiddenFields = (dependencies) => {
  let hiddenFields = {};

  if (dependencies === null) {
    return hiddenFields;
  }

  for (const key in dependencies) {
    if (dependencies[key].hasOwnProperty('affects')) {
      hiddenFields[key] =
    } else {

    }
  }

  return hiddenFields;
}

But I am lost as to how to finish this. I know I want it recursive, but I also want it fast, but still legible.

Any Ideas?

2
  • 1
    status has an affects key. Why doesn't it have hide: true after "value": "Deceased" in the output? Commented Sep 3, 2019 at 17:24
  • @adiga Great question, status is a field (a choice field in this case) and when you select a value, in this case Deceaed then we want to show the other fields: cause of death and date of death. If you then select other from cause of death we then show other cause of death. Commented Sep 3, 2019 at 17:38

3 Answers 3

1

You're probably looking for something like

export function createHiddenFields(dependencies) {
  if (Array.isArray(dependencies)) {
    return dependencies.map(createHiddenFields);
  }
  const hiddenFields = {
    hide: true,
  };
  if (typeof dependencies == 'object' && dependencies !== null) {
    for (const key in dependencies) {
      if (key == 'affects') {
        hiddenFields.affects = createHiddenFields(dependencies.affects);
      } else {
        hiddenFields[key] = dependencies[key];
      }
    }
  }
  return hiddenFields;
}
Sign up to request clarification or add additional context in comments.

4 Comments

typeof depencies will never be an object... You mean dependencies, right? ;-)
@FZs Sure, thanks. I wouldn't have minded if you just edited my answer :-)
@Bergi Yeah, but people are usually careful about editing code in other's posts.
@TomášZato In obvious cases like this, one may be bold :-)
0

You can do this using recursion and for...in loop and check if the value of the property is object then call the function again or if its not then add the value.

const data = {"comorbidities":[{"affects":{"malignancy_type":{"affects":{"malignancy_type_other":"malignancy_type_other"},"value":"Other"}},"value":"malignancy"},{"affects":{"heritable_syndrome_type":"heritable_syndrome_type"},"value":"heritable syndrome"}]}

function update(obj, val) {
  for (let i in obj) {
    if (typeof obj[i] == 'object') update(obj[i], val);
    else if ('affects' in obj) Object.assign(obj, val);
    else obj[i] = val
  }
}

update(data, {hide: true});
console.log(data)

2 Comments

You shouldn't use for…in enumerations on arrays though, so I'd expect an extra if (Array.isArray(obj)) … check
else if ('affects' in obj) Object.assign(obj, val); shouldn't be inside the loop. It just does the same hing for every iteration multiple times for no good reason.
0

I decided to post a late answer anyway, because I see some possible flaws and gotchas in the other answers. Specifically:

  • for ... in is dangerous because it may loop over any iterable Object.prototype propertyes, which sometimes exist thanks to irresponsible developers. In general it loops over all properties including inherited ones
  • for ... in is not supposed to be used for looping over an array
  • It may be unwise to reuse the {hide: true} object. Should you later wish to alter the hide property for some entries in the tree, it would affect all that share the same object reference

So I'd instead write a longer but safer method:

function createHiddenFields(obj) {
  // ignore nulls
  if(obj == null) {
    return;
  }
  // For an array, just do the update for each object in array
  else if(obj instanceof Array) {
    for(const subObj of obj) {
      createHiddenFields(subObj);
    }
  }
  // For object, do the hidden field thing
  else if(typeof obj == "object") {
    // Replace all string values with hiddenVal
    for(const valueName of Object.getOwnPropertyNames(obj)) {
      // Do not override value nodes
      if(valueName == "value") {
        continue;
      }
      else {
        // Process sub-objects
        if(typeof obj[valueName] == "object") {
          createHiddenFields(obj[valueName]);
        }
        // Replace primitive property values
        else {
          obj[valueName] = { hide: true };
        }
      }
    }
    // add hidden field for affects
    if(typeof obj.affects == "object") {
      obj.hide = true;
    }
  }
}

demo

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.