2

I have a general function that I want to call with any object structure. Some of the objects has arrays of objects which then again have arrays of objects etc.

The only way I got it to work was like this and it does not seem like the most clever way of doing it cause I keep adding depth to the function.

Is there a better way? I tried a recursive function I found here on stack, but couldn't get it to work.

// Look for everyting at level ONE
for (var property in textfield) {
  // Is there a field?
  if (textfield.hasOwnProperty(property)) {
    // Is level ONE an OBJECT
    if (typeof textfield[property] == "object") {
      // Look for everyting at level TWO
      for (var subProperty in textfield[property]) {
        // Is there a field?
        if (textfield[property].hasOwnProperty(subProperty)) {
          // Is level TWO an OBJECT
          if (typeof textfield[property][subProperty] == "object") {
            // Look for everyting at level THREE
            for (var subSubProperty in textfield[property][subProperty]) {
              // Is there a field?
              if (textfield[property][subProperty].hasOwnProperty(subSubProperty)) {
                // Is level THREE an OBJECT
                if (typeof textfield[property][subProperty][subSubProperty] == "object") {
                  // Look for everyting at level FOUR
                  for (var subSubSubProperty in textfield[property][subProperty][subSubProperty]) {
                    // Translate everything at level FOUR
                    console.log("-----------------------LEVEL 4")
                    console.log("LOOP: " + textfield[property][subProperty][subSubProperty][subSubSubProperty]);
                    console.log("TYPE: " + typeof textfield[property][subProperty][subSubProperty][subSubSubProperty]);
                    textfield[property][subProperty][subSubProperty][subSubSubProperty] = replaceFields(textfield[property][subProperty][subSubProperty][subSubSubProperty]);
                  }
                } else {
                  // Translate everything at level THREE
                  console.log("-----------------------LEVEL 3")
                  console.log("LOOP: " + textfield[property][subProperty][subSubProperty]);
                  console.log("TYPE: " + typeof textfield[property][subProperty][subSubProperty]);
                  textfield[property][subProperty][subSubProperty] = replaceFields(textfield[property][subProperty][subSubProperty]);
                }
              }
            }
          } else {
            // Translate everything at level TWO
            console.log("-----------------------LEVEL 2")
            console.log("LOOP: " + textfield[property][subProperty]);
            console.log("TYPE: " + typeof textfield[property][subProperty]);
            textfield[property][subProperty] = replaceFields(textfield[property][subProperty]);
          }
        }
      }
    } else {
      // Translate everything at level ONE
      console.log("-----------------------LEVEL 1")
      console.log("LOOP: " + textfield[property]);
      console.log("TYPE: " + typeof textfield[property]);
      textfield[property] = replaceFields(textfield[property]);
    }
  }
}

Thanks to Jinweizhu's answer below, this is the final version and it works perfectly!!

function translateAll(textfield) {
    for (var property in textfield) {
        if (!textfield.hasOwnProperty(property)) {
            return false;
        } else if (typeof textfield[property] !== "object") {
            textfield[property] = replaceFields(textfield[property]);
        } else {
            translateAll(textfield[property]);
        }
    }
}
5
  • 1
    Give an example object, and show us the recursion function you've tried so we can fix it, ideally as minimal reproducible example. Commented Jul 13, 2020 at 12:08
  • 1
    can you provide an example of how array of objects could look like? Commented Jul 13, 2020 at 12:09
  • 1
    Recursion is the better way. This might help: How can I access and process nested objects, arrays or JSON? Commented Jul 13, 2020 at 12:09
  • 1
    does your object contain not own properties? Commented Jul 13, 2020 at 12:10
  • You are right guys, let me find a proper example Commented Jul 13, 2020 at 14:54

2 Answers 2

2

I'm not sure what you mean is the same as what I understand.

let index = 0;
function fn(textfield) {
    index++;
    for (var property in textfield) {
        if (!textfield.hasOwnProperty(property)) {
            return false;
        } else if (typeof textfield[property] !== "object") {
            console.log("-----------------------LEVEL " + index);
            console.log("LOOP: " + textfield[property]);
            console.log("TYPE: " + typeof textfield[property]);
            // textfield[property] = replaceFields(textfield[property]);
        } else {
            fn(textfield[property]);
        }
    }
}
const obj = {a:{ b: { c: { d:1} } }};
fn(obj);
Sign up to request clarification or add additional context in comments.

2 Comments

your index made this one easier to understand and debug - I will try it out!
simple and elegant - see my original post where I put the final result of your idea after testing!!
2

I'm not sure what do you want to do with your objects or arrays values but I hope this will help you. The following function prints the values and calls itself recursively in case of objects or arrays:

const getValues = (value, path = '') => {  
  if (typeof value === 'object'
    && value !== null
    && value.length === undefined
    && Object.keys(value).length > 0) {
    // It is an Object (not null, array or Date instance)
    Object.keys(value).forEach((prop) => {
      const _path = path.length ? `${path}.${prop}` : prop;
      getValues(value[prop], _path);
    });
  } else if (typeof value === 'object'
    && value !== null
    && value.length  > 0) {
    // It is an array
    value.forEach((item, idx) => {
      const _path = path.length ? `${path}[${idx}]` : idx;
      getValues(item, _path);
    });
  } else {
    console.log(`${path} = ${JSON.stringify(value)}`);
  }
};

For example:

const obj = {
  a: 1,
  b: { a: 1, b: 2 },
  c: [
    { a: 1, b: 2 },
    { a: 1, b: 2 },
  ],
  d: {},
  e: [],
  f: new Date(),
  g: null,
  h: undefined,
};
getValues(obj, 'obj');

Will output:

obj.a = 1
obj.b.a = 1
obj.b.b = 2
obj.c[0].a = 1
obj.c[0].b = 2
obj.c[1].a = 1
obj.c[1].b = 2
obj.d = {}
obj.e = []
obj.f = "2020-07-14T06:02:12.037Z"
obj.g = null
obj.h = undefined

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.