-1

I suspect the answer is "you can't" but there are a lot of people here who are brighter than I. In reviewing (and re-writing) code I wrote a year-ish ago (before I learned redux), I have a react component that contains the following destructing of a user profile passed to as a prop as user:

  const {user} = props;
  const {
    email, username, salutation, firstName, middleName, lastName, suffix, company, title, 
    securityQuestionNo1, securityAnswerNo1, securityQuestionNo2, securityAnswerNo2,
    securityQuestionNo3, securityAnswerNo3, email1, email2, telNo, altTelNo, shippingAddress1, 
    shippingAddress2, shippingAddress3, shippingCity, shippingState, shippingPostalCode, 
    shippingNation, billingAddress1, billingAddress2, billingAddress3, billingCity, 
    billingState, billingPostalCode, billingNation, planChoice, cardName, cardType, cardNumber,
    expiryMM, expiryYYYY, cvv,
  } = user;

Is there a less ghastly way to declare all these variables inside my component? Is there anyway to move this eyesore above into a separate file and import the variables? Something that's better than changing all subsequent appearances of these variables user.email, user.username, etc. (I thought of using var and moving the declaration to the bottom of the file, but these are not things that should be global variables.)

To the person who suggested that string editing was the way to go, the answer is NO, because (a) it's slow because converting between JSON.stringify objects and back to objects is slow, (b) it's also insecure (someone can inject a string into you code easily enough, since this code will be running on the front end), and (c) it's terrible form, for which Uncle Bob, should he do JS, would scold you extensively.

Charles Goodwin
  • 584
  • 5
  • 8
  • I think convert above variable named users into one json file is one solution, then import it when be needed. – Sphinx Jun 25 '20 at 22:14
  • 1
    Do you really need all of these variables in this one component? Perhaps you could extract things like the user's general information, security questions, billing information and payment information into their own components which just take the `user` object in and destructure the variables they need inside, and render them in whatever way you are rendering them in this component. – cbr Jun 25 '20 at 22:20
  • 2
    But if you really really **really** have a good reason for it and weigh the pros to be much heavier than the cons, javascript does have a [`with` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with) which, however, is quite obscure and very rarely used. – cbr Jun 25 '20 at 22:31
  • 1
    Does this answer your question? [Convert string to variable name in JavaScript](https://stackoverflow.com/questions/5613834/convert-string-to-variable-name-in-javascript) I mean, in a combination with a `for...in` loop. – Niklas E. Jun 25 '20 at 22:41

3 Answers3

3

No, there is not. If you want the variables, you have to declare them.

Your underlying issue appears to be that your user object has far too many properties. Use a composite of many smaller objects instead. Put everything with a common prefix in a sub-structure at least. Use arrays instead of numbering your properties. A user doesn't have a cardtype, a user has a card which has a type.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • The problem with the code one wrote a thousand hours of coding ago is that it would take a lot of refactoring to fix *that* problem. – Charles Goodwin Jun 25 '20 at 22:50
  • 1
    Yes, it will. Just do it one step at a time. First extract the card stuff, then the billing stuff, then the shipping stuff, then the security stuff… If you actually used each of these variables individually in your component, there's no way to get around fixing this problem. If the destructuring is so ghastly long, I would expect to rest of the component to be just as ghastly. You're rewriting it because you want to fix *that*, no? – Bergi Jun 25 '20 at 23:18
  • 2
    Notice there's nothing wrong with long code by itself. If you need it, then write it out, even if it's a thousand variables. Sure, there might be tricks to avoid the destructuring like the `with` statement @cbr mentioned in the comments, but you'd still be using a thousand variables in your component. To make this code better™, you will need to bring structure into there: not in the declaration, but in the usage. Start small. – Bergi Jun 25 '20 at 23:23
0

Why don't you use the new optional chaining operator ?.. It short-circuits if the left-hand side is null or undefined and the entire expression yields null. For example, const x = a?.b?.c is roughly equivalent to:

const x = a === null || a === undefined
        ? undefined
        : a.b === null || a.b === undefined
        ? undefined
        : a.b.c
        ;

Then you can dispense with the destructuring and just say things like

if ( user?.email ) {
  sendEmail(user);
}
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
-1

There is away to get around that

user={ email:"as@gmail.com", username:1, salutation:"hi", firstName:"smith", middleName:"do", lastName:"wi", suffix:"suf", company:"sm", title:"se", 
  securityQuestionNo1:"smth", securityAnswerNo1:"js", securityQuestionNo2:"script", securityAnswerNo2:"node"}

Object.entries(user).forEach((item) => {
  globalThis[item[0]] = item[1] // use window instead of glabalThis if you are not using Nodejs
})

console.log(email, username, salutation, firstName, middleName)
Sven.hig
  • 4,449
  • 2
  • 8
  • 18