0

I want to destructure a dynamic key from a object, where `key` is some pattern. There is counter appended to key.

var obj = {
 "key2":{"left":{"content": "This data to be pulled"}},
 "hasErrorcharges2":false,
 "hasErrorcharges2_Card":""
}
const {key2: {left: content }} = obj;

Here key2 is dynamic. So we know that it will always start with key and the other values can be key0, key1, key3 and hence forth. How do we traverse in this case?

Things tried.

  1. Match the if object has any key similar to it. and then return the matched key. but got true false

  2. can't destructure dynamic prop. but in this we know a pattern

  3. traverse through the object with dynamic property and get the value.

  4. expecting to write a similar function like hasOwn() or hasOwnProperty

2
  • 1
    If you don’t know the key in advance, you can’t use destructuring. Not sure what specifically you’ve tried, but get familiar with how to access and process objects, arrays, or JSON, and use the static and instance methods of Object and Array. It looks like you can just use find and startsWith on the result of Object.keys or Object.entries. Commented Jan 16, 2023 at 10:48
  • It is not entirely clear what target structure the OP wants the original data structure be transformed into, since the OP did not provide the expected result. Maybe the OP could get some ideas from the answer(s) of following question ... "How does one detect and access numbered property names like 'entry1', 'entry2'?" Commented Jan 16, 2023 at 14:29

1 Answer 1

2

You can't do the destructuring until you know the name of the property. You can find it by using find on Object.keys (but keep reading for an alternative). Then you can use computed property notation to specify that name in the destructuring expression. (There's also a small error in that expression, see the highlighted bit below.)

const keyName = Object.keys(obj).find((key) => key.startsWith("key"));
if (keyName) {
    const {
//      vvvvvvvvv−−−−−−−−−−−−−−−−−−−−−−−−−− computed property notation
        [keyName]: { left: { content } },
//                         ^−−−−−−−−−^−−−−− minor correction to destructuring
    } = obj;
    // ...
}

There I've just checked that the property name starts with key — you might want to beef up the condition in the find callback, but that's the general idea.

Live Example:

const obj = {
    key2: { left: { content: "This data to be pulled" } },
    hasErrorcharges2: false,
    hasErrorcharges2_Card: "",
};
const keyName = Object.keys(obj).find((key) => key.startsWith("key"));
if (keyName) {
    const {
        [keyName]: { left: { content } },
    } = obj;
    console.log(`content = ${content}`);
}


That said, if you need to loop through the object properties anyway, it may not be worth setting yourself up for destructuring vs. just grabbing the property in a loop and breaking when you find it:

let content = null;
for (const key in obj) {
    if (key.startsWith("key")) {
        content = obj[key].left.content;
        break;
    }
}
if (content !== null) { // Valid only if we know content won't be `null` in the object
    // ...
}

Live Example:

const obj = {
    key2: { left: { content: "This data to be pulled" } },
    hasErrorcharges2: false,
    hasErrorcharges2_Card: "",
};
let content = null;
for (const key in obj) {
    if (key.startsWith("key")) {
        content = obj[key].left.content;
        break;
    }
}
if (content !== null) { // Valid only if we know content won't be `null` in the object
    console.log(`content = ${content}`);
}

If you like, this:

content = obj[key].left.content;

could be:

({ content } = obj[key].left);

...which avoid repeating the identifier content. Or even:

({left: { content }} = obj[key]);

...though there's really no need to use the nested destructuring, it doesn't save you anything. :-)

(We need the () around it because otherwise the { at the beginning looks like the beginning of a block to the JavaScript parser.)

Sign up to request clarification or add additional context in comments.

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.