Timo Ernst
Timo Ernst

Reputation: 15993

How can this dom-to-vars code be shortened in JavaScript?

Just found this code in a YouTube tutorial and found it to be very verbose:

Verbose JS code

So I thought, can't this be shortened? Isn't there some kind of ES2015 magic or so that can make this a one-liner?

The smartest that I could come up with was this:

const els = ['txtEmail', 'txtPassword', 'btnLogin', 'btnSignUp', 'btnLogout'];
const values = {};
for (var i=0; i<els.length; i++) {
  values[els[i]] = document.getElementById(els[i]);
}

This isn't much shorter but if there were more dom elements this would definitely pay off in the long run.

However, how can this be optimized to be as non-verbose as possible?

Upvotes: 0

Views: 71

Answers (4)

guest271314
guest271314

Reputation: 1

You can use destructuring assignment

const [txtEmail, txtPassword, btnLogin, btnSignUp, btnLogout] = [
      document.getElementById("txtEmail")
      , document.getElementById("txtPassword")
      , document.getElementById("btnLogin")
      , document.getElementById("btnSignUp")
      , document.getElementById("btnLogout")
      ];

console.log(txtEmail, txtPassword, btnLogin, btnSignUp, btnLogout);
<input id="txtEmail">
<input id="txtPassword">
<input id="btnLogin">
<input id="btnSignUp">
<input id="btnLogout">

Alternatively, using .querySelectorAll() with attribute begins with selector and spread element

const [txtEmail, txtPassword, btnLogin, btnSignUp, btnLogout] = [
      ...document.querySelectorAll("input[id^=txt]")
      , ...document.querySelectorAll("input[id^=btn]")
      ];
      
console.log(txtEmail, txtPassword, btnLogin, btnSignUp, btnLogout);
<input id="txtEmail">
<input id="txtPassword">
<input id="btnLogin">
<input id="btnSignUp">
<input id="btnLogout">

Upvotes: 0

Jonas Wilms
Jonas Wilms

Reputation: 138457

Another solution

var fields={
txtEmail,
txtPassword
}

Object.keys(fields).forEach(e=>fields[e]=document.getElementById(e));

console.log(fields.txtEmail);

Upvotes: 0

kamoroso94
kamoroso94

Reputation: 1735

You could make a list of elements with map.

const ids = ["txtEmail", "txtPassword", "btnLogin", "btnSignUp", "btnLogout"];
const elems = ids.map(id => document.getElementById(id));

Or you could make an object with reduce.

const ids = ["txtEmail", "txtPassword", "btnLogin", "btnSignUp", "btnLogout"];
const elems = ids.reduce((obj, id) => {
    obj[id] = document.getElementById(id);
    return obj;
}, {});

Upvotes: 2

epascarello
epascarello

Reputation: 207537

With reduce

const els = ['txtEmail', 'txtPassword', 'btnLogin', 'btnSignUp', 'btnLogout'];
const elms = els.reduce( (o, id) => { 
  o[id] = document.getElementById(id); 
  return o
}, {} )

without the fat arrow

const els = ['txtEmail', 'txtPassword', 'btnLogin', 'btnSignUp', 'btnLogout'];
const elms = els.reduce( function (o, id) { 
  o[id] = document.getElementById(id); 
  return o
}, {} )

In the end, not sure what the benefit of it is....

Upvotes: 0

Related Questions