0

I'm having issues getting input from a document and outputting it using the this keyword. When outright calling the object and attribute followed by .value I didn't encounter a problem, but trying to use this has become a complication. Calling person.display results in undefined areas. I've looked for how to get a value for this and I'm starting to get further away from the solution. Could someone provide help?

HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Lesson 11 Lab</title>
</head>
<body>
    <label for="first_name">Enter first name:</label><br>
    <input type="text" id="first_name"><br><br>
    <label for="last_name">Enter last name:</label><br>
    <input type="text" id="last_name"><br><br>
    <label for="course">Enter your course:</label><br>
    <input type="text" id="course"><br><br>
    <label for="section">Enter your section:</label><br>
    <input type="text" id="section"><br><br>
    <label for="role">Enter your role:</label><br>
    <input type="text" id="role"><br><br>
    <input type="button" id="button1" value="Show: Person/Class/Role"><br>
    <p id="fill_in"></p>
    <script src="person_java.js"></script>
</body>
</html> 

JavaScript

let person = {
    first_name: document.getElementById("first_name"),
    last_name: document.getElementById("last_name"),
    course: document.getElementById("course"),
    section: document.getElementById("section"),
    role: document.getElementById("role"),
    display: function() {
        document.getElementById("fill_in").innerHTML = this.first_name + " " + this.last_name + " has the role of " + this.role + " in " + this.course + " section " + this.section + "."; 
    }
};

document.getElementById("button1").addEventListener("click", );
  • 1
    `this.first_name` -> `this.first_name.value` (assuming it's an input) or `this.first_name.textContent` (assuming it's another element). Same for all the otherrs. – VLAZ Nov 29 '21 at 15:32
  • 2
    Which code produces undefined “areas”? Have you tried `document.getElementById("button1").addEventListener("click", person.display.bind(person));`? – Sebastian Simon Nov 29 '21 at 15:32
  • Using bind results in this output: [object HTMLInputElement] [object HTMLInputElement] has the role of [object HTMLInputElement] in [object HTMLInputElement] section [object HTMLInputElement]. – Kyle Davis Nov 29 '21 at 15:36
  • Using .value or .textContent results in the button not outputting anything. – Kyle Davis Nov 29 '21 at 15:39
  • _“results in the button not outputting anything”_ — Perfect opportunity to learn about [how to debug small programs](//ericlippert.com/2014/03/05/how-to-debug-small-programs/). Please try using the [debugging capabilities](//ali-dev.medium.com/how-to-easily-debug-in-javascript-5bac70f94f1a) of your browser. Use the [browser console (dev tools)](//webmasters.stackexchange.com/q/8525) (hit `F12`) and read any errors. – Sebastian Simon Nov 29 '21 at 15:41
  • Uncaught TypeError: Cannot read properties of undefined (reading 'textContent') at HTMLInputElement.display – Kyle Davis Nov 29 '21 at 15:42
  • Using `person.display.bind(person)` and `.value` [should work fine](https://jsfiddle.net/hyLz4n7c/). – Ivar Nov 29 '21 at 15:43
  • @KyleDavis Why are you using `.textContent` now? Now that it’s clear that everything is an ``, only `.value` should be used. Make sure you put `.value` on `this.first_name`, etc., not on `document.getElementById("first_name")`, etc. Please [edit] your post and provide a [mre] of the code that produces this error. See [How to create Stack Snippets](//meta.stackoverflow.com/q/358992/4642212). – Sebastian Simon Nov 29 '21 at 15:44
  • Really appreciate the help. I've tried to edit the post to include everything necessary. In the future I'll know I can use something like jsfiddle. For whatever reason I was under the impression that when using 'this' you can't use .value. Not sure where I got that from. – Kyle Davis Nov 29 '21 at 15:51
  • 1
    @KyleDavis Note that _only_ using JSFiddle is insufficient. Questions must be self-contained, so all the code necessary to reproduce an issue must be in the question itself. Stack snippets can be used for demos _like_ JSFiddle. – Sebastian Simon Nov 29 '21 at 15:54
  • Understood. I'll be sure to include everything initially the next time. Why is it that I couldn't call the object's function without wrapping the it in a function itself? – Kyle Davis Nov 29 '21 at 15:56
  • 1
    @KyleDavis Because the `this` depends on how the function is called. When you pass `person.display` to `.addEventListener()`, you are _only_ passing the function itself, without the `person` context. See [How does the "this" keyword work?](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Ivar Nov 29 '21 at 16:10
  • @KyleDavis See also [How to access the correct `this` inside a callback](/q/20279484/4642212). – Sebastian Simon Nov 29 '21 at 16:31

1 Answers1

0

You need to reference the value when you are building the string. You need to call your function onclick. With those changes, your code will work fine.

let person = {
  first_name: document.getElementById("first_name"),
  last_name: document.getElementById("last_name"),
  course: document.getElementById("course"),
  section: document.getElementById("section"),
  role: document.getElementById("role"),
  display: function() {
    document.getElementById("fill_in").innerHTML = this.first_name.value + " " + this.last_name.value + " has the role of " + this.role.value + " in " + this.course.value + " section " + this.section.value + ".";
  }
};

document.getElementById("button1").addEventListener("click", function (){
  person.display();
});
<label for="first_name">Enter first name:</label><br>
<input type="text" id="first_name"><br><br>
<label for="last_name">Enter last name:</label><br>
<input type="text" id="last_name"><br><br>
<label for="course">Enter your course:</label><br>
<input type="text" id="course"><br><br>
<label for="section">Enter your section:</label><br>
<input type="text" id="section"><br><br>
<label for="role">Enter your role:</label><br>
<input type="text" id="role"><br><br>
<input type="button" id="button1" value="Show: Person/Class/Role"><br>
<p id="fill_in"></p>
epascarello
  • 204,599
  • 20
  • 195
  • 236