18

The function below receives an object that has a property current, which is also an object, and it has selectionStart and selectionEnd properties.

Here, nested destructuring works as expected with Start and End variables, But I also need the value for current.

function someFunction({ current: { selectionStart: Start, selectionEnd: End } }) {

    // do something with current, Start, and End
}

How do I get it using destructuring?

soufiane yakoubi
  • 861
  • 11
  • 31
  • i understand that i can go to deep levels of an object by destructuring , but i couldn't find how to get the value of the object it self , not its properties . so in this particular case , i don't know how to get the value of current . – soufiane yakoubi Feb 08 '19 at 11:25
  • You should try to word your question better to clarify that `Start` and `End` are working properly, but `current` is undefined. @adiga has just answered this. – caesay Feb 08 '19 at 11:26
  • @caesay , is it clear now ? if it's not please let me know . thank you . – soufiane yakoubi Feb 08 '19 at 11:38

3 Answers3

26

The first destructuring creates only Start and End variables. If you want to create current as a variable, then you need to declare it again.

function ({ current: { selectionStart: Start, selectionEnd: End }, current }, AppStateSetter) {

// do something with current , Start , and End

}

You can test it on the Babel compiler:

This code:

const object = {
  current: {
    selectionStart: "prop 1",
    selectionEnd: "prop2"
  }
}

const { current: { selectionStart: Start, selectionEnd: End } } = object;

Gets trasnpiled to:

var object = {
  current: {
    selectionStart: "prop 1",
    selectionEnd: "prop2"
  }
};

var _object$current = object.current,
    Start = _object$current.selectionStart,
    End = _object$current.selectionEnd;

As you can see, current variable is not created.

adiga
  • 34,372
  • 9
  • 61
  • 83
  • A note to remember, best practise is to spread the remaining props. So if you used `...rest` (name could be anything). You could have accessed current via `rest.current` – Neil Jun 01 '19 at 23:13
  • 1
    @Neil `rest` won't have `current` [Babel](https://babeljs.io/repl#?babili=false&browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=MYewdgzgLgBA3jYBXATigpmKAueMLoA26wUAluAMpQCGKOM1dUANPkSeeAKJgAmuXnxgBfNgDpJGaKJgBeGDQDcQA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=false&presets=env&prettier=false&targets=&version=7.4.5&externalPlugins=) – adiga Jun 02 '19 at 05:02
  • If `...rest` is added after that last property `selectionEnd`. Then this will be the remainder object props. I did not notice the second level destructure. – Neil Jun 02 '19 at 09:17
3

I think the issue you are facing happens when current is undefined.

You can try destructing with default value.

function ({ current: { selectionStart: Start, selectionEnd: End } = {} }, AppStateSetter) {
  // do something with Start and End
}

If you think you need to access current as well, try destructuring inside the function.

function ({ current = {}}, AppStateSetter) {
  const { selectionStart: Start, selectionEnd: End } = current
  // do something with current, Start and End
}
Dinesh Pandiyan
  • 5,814
  • 2
  • 30
  • 49
2

You can destructure and assign the default value in a single statement.

function someFunction({
        current: {
          selectionStart: Start,
          selectionEnd: End
        } = {},
        current = {}
      },
      AppStateSetter) {
      // now you can use the let variables Start, End and current,
      // with current's default value set to empty object
      }

If you don't want to assign default value to current, but still want to use that variable, you can just write the name of the property with no assignment. When someFunction is called with empty object, if you don't assign a default value to current it will be undefined.

    function someFunction1({
        current: {
          selectionStart: Start,
          selectionEnd: End
        } = {},
        current
      },
      AppStateSetter) {
      // now you can use the let variables Start, End and current
      // if empty object is passed, current will be undefined
    }

JsFiddle snippet: Nested object destructuring with and without default values