0

In the following code I'm trying to create a human object from form data. The userData object returns undefined for all values but I am assigning values in the function that retrieves the data. If I console.log the userData object I see '{}' then when expanding I see the values but after creating the human object those same values show undefined. How can I assign those values to the human object so it keeps those values? Thank you.

function Human(name, height, weight, diet) {
    this.name = name;
    this.height = height;
    this.weight = weight;
    this.diet = diet;
}
    
const btn = document.getElementById('btn');
const userData = {};
function getUserData() {
    let formContainer = document.getElementsByClassName('form-container')[0];

    formContainer.style.display = 'none';
    let main = document.getElementById('grid');
    main.style.display = 'flex';

    let name = document.getElementById('name').value;
    let feet = parseFloat(document.getElementById('feet').value);
    let inches = parseFloat(document.getElementById('inches').value);
    let height = (feet * 12) + inches;
    let weight = parseFloat(document.getElementById('weight').value);
    let diet = document.getElementById('diet').value;

    userData.name = name;
    userData.height = height;
    userData.weight = weight;
    userData.diet = diet;

}

console.log(userData);
// Create Human Object
const human = new Human(userData.name, userData.height, userData.weight, userData.display);
console.log(human);
3
  • 1
    firstly your problem is not clear. At least, I couldn't really understand. Secondly, is getUserData function ever called in somewhere before you print userData Commented Sep 2, 2020 at 6:30
  • Yes. I updated the post. I am calling the getUserData on button click and trying to create object from the retrieved data. Commented Sep 2, 2020 at 7:42
  • @larry8989 have you seen my answer below. Its exactly working as you wanted in your form with a button click - Let me know Commented Sep 2, 2020 at 8:11

4 Answers 4

2

I think you might want to refactor to this instead so that the function getUserData() is more reusable.

function getUserData() {

    let formContainer = document.getElementsByClassName('form-container')[0];
    formContainer.style.display = 'none';

    let main = document.getElementById('grid');
    main.style.display = 'flex';

    const name = document.getElementById('name').value;
    const feet = parseFloat(document.getElementById('feet').value);
    const inches = parseFloat(document.getElementById('inches').value);
    const height = (feet * 12) + inches;
    const weight = parseFloat(document.getElementById('weight').value);
    const diet = document.getElementById('diet').value;

    return {name, height, weight, diet}
}

const userData = getUserData()
const human = new Human(userData.name, userData.height, userData.weight, userData.diet);
Sign up to request clarification or add additional context in comments.

Comments

1

You can use JavaScript class and a constructor method to store your userData data. So that you can use access your data via new Human class.

Ideally in modern JS you want to class function instead of simple as this be re-useable as well as the simple one but its a good practice to use a class function since that's what you are trying to do as well.

Live Working Demo:

const btn = document.getElementById('btn');
let userData = {};

class Human {
  constructor(name, height, weight, diet) {
    this.name = name;
    this.height = height;
    this.weight = weight;
    this.diet = diet;
  }
}

function getUserData() {
  let name = document.getElementById('name').value;
  let feet = parseFloat(document.getElementById('feet').value);
  let inches = parseFloat(document.getElementById('inches').value);
  let height = (feet * 12) + inches;
  let weight = parseFloat(document.getElementById('weight').value);
  let diet = document.getElementById('diet').value;

  //Store to object
  userData.name = name;
  userData.height = height;
  userData.weight = weight;
  userData.diet = diet;
}

// call getUserData on button click
btn.addEventListener('click', function(e) {
  e.preventDefault()

  getUserData() //call function on click

  // Create Human Object
  const human = new Human(userData.name, userData.height, userData.weight, userData.diet);
  console.log(human); //create object

});
<form id="dino-compare">
  <div class="form-container">
    <p>Name:</p>
    <input id="name" class="form-field__full" type="name" name="name">
    <p>Height</p>
    <label>Feet: <input id="feet" class="form-field__short" type="number" name="feet"></label>
    <label>inches: <input id="inches" class="form-field__short" type="number" name="inches"></label>
    <p>Weight:</p>
    <label><input id="weight" class="form-field__full" type="number" name="weight">lbs</label>
    <p>Diet:</p>
    <select id="diet" class="form-field__full" name="diet">
      <option>Herbavor</option>
      <option>Omnivor</option>
      <option>Carnivor</option>
    </select>
    <button id="btn" onclick="getUserData(event)">Compare Me!</button>
  </div>
</form>

3 Comments

Strictly speaking, any function (except for => functions) can be used as a constructor, just by using the new keyword when calling it. The class declaration is unnecessary in this case, but it is a good idea to use it in modern JS.
but it is a good idea to use it in modern JS => thats why i added the class function instead of simple one.
Right. It's best practice. But if you read an older tutorial before the class keyword was introduced, you would see the style the OP used. I think it's important to explain that both styles are correct, to prevent confusion, and explain when to use one vs. the other
1

You can use the jQuery serializaArray() method

  function Human(name, height, weight, diet) {
      this.name = name;
      this.height = height;
      this.weight = weight;
      this.diet = diet;
  }

  (function ($) {
      $.fn.serializeFormJSON = function () {

          var o = new Human();
          var a = this.serializeArray();
          $.each(a, function () {
              if (o[this.name]) {
                  if (!o[this.name].push) {
                      o[this.name] = [o[this.name]];
                  }
                  o[this.name].push(this.value || '');
              } else {
                  o[this.name] = this.value || '';
              }
          });
          return o;
      };
  })(jQuery);

  $('form').submit(function (e) {
      e.preventDefault();
      var data = $(this).serializeFormJSON();
      console.log(data);
  });

fiddle: https://jsfiddle.net/mL32gvd0/1/

Comments

0

because you never call getUserData function

it may look like following:

getUserData();
console.log(userData);
const human = new Human(userData.name, userData.height, userData.weight, userData.display);
console.log(human);

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.