Uncaught TypeError in javascipt - javascript

I've been trying to use the this keyword to fetch a dataset but I keep getting the Uncaught TypeError: Cannot read property 'page' of undefined, In the below script what I'm trying to achieve is that whenever a button is clicked then it displays certain content and hide all other things
<!DOCTYPE html>
<html>
<head>
<title>Show Page</title>
<script>
function showPage(division){
document.querySelectorAll('h1').style.display = 'none';
document.querySelector(divsion).style.display = 'block';
}
document.addEventListener('DOMContentLoaded',() => {
document.querySelectorAll('button').forEach(button => {
button.onclick = () => {
showPage(this.dataset.page);
}
});
});
</script>
</head>
<body>
<button data-page="page1">Page1</button>
<button data-page="page2">Page2</button>
<button data-page="page3">Page3</button>
<h1 id="page1">This is page1</h1>
<h1 id="page2">This is page2</h1>
<h1 id="page3">This is page3</h1>
</body>
</html>

Use function() {} in your click handler, to be in the correct context. Arrow functions keep the surrounding context:
document.querySelectorAll('button').forEach(button => {
button.onclick = function() {
console.log(this.dataset.page);
}
});
<button data-page="page1">Page1</button>
<button data-page="page2">Page2</button>
<button data-page="page3">Page3</button>

If you use arrow function then this will not contain the current element, you need to pass a parameter(event) in the function, get its current target and then get the properties.
function showPage(division) {
document.querySelectorAll('h1').style.display = 'none';
document.querySelector(divsion).style.display = 'block';
}
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('button').forEach(button => {
button.onclick = (e) => { // pass a parameter here
//showPage(e.currentTarget.dataset.page); // get current target of event and its property.
console.clear();
console.log(e.currentTarget.dataset.page); // output on console
}
});
});
<!DOCTYPE html>
<html>
<head>
<title>Show Page</title>
</head>
<body>
<button data-page="page1">Page1</button>
<button data-page="page2">Page2</button>
<button data-page="page3">Page3</button>
<h1 id="page1">This is page1</h1>
<h1 id="page2">This is page2</h1>
<h1 id="page3">This is page3</h1>
</body>
</html>
See if it helps you.

Related

TypeError: Cannot read properties of null (reading 'style') at handleClick

I want to change my target div variable's display property from none to block.
const userListEl = document.getElementById('user-list').innerHTML;
const template = Handlebars.compile(userListEl);
const targetDiv = document.getElementById("userDetail");
fetch("https://5dc588200bbd050014fb8ae1.mockapi.io/assessment")
.then(response => response.json())
.then((data) => {
var userData = template({ usersList: data })
document.getElementById('test').innerHTML = userData;
}).catch((error) => {
console.log(error)
})
this is my function
const hanldeClick = () => {
if (targetDiv.style.display === "none") {
targetDiv.style.display = "block";
} else {
targetDiv.style.display = "none";
}
};
#userDetail {
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Exercise 1</title>
</head>
<body>
<div id="test"></div>
<script id="user-list" type="text/x-handlebars-template">
<ul class="people_list"> {{#each usersList}}
<li>
<p class="">{{name}}</p>
<img src={{avatar}} alt={{name}}>
<div id="userDetail">
<p>Id: {{id}}</p>
<p>Created at: {{createdAt}}</p>
</div>
<button onclick="hanldeClick()"> Detail </button>
</li>
{{/each}}
</ul>
</script>
<script type="text/javascript" src="app.js" defer></script>
<script src="https://cdn.jsdelivr.net/npm/handlebars#latest/dist/handlebars.js"></script>
</body>
I want to change the display value none to block in an onclick handler, but when the button is clicked I get this error:
TypeError: Cannot read properties of null (reading 'style')
Can someone help me?
targetDiv is null when you click the "Detail" button and trigger the handleClick function because there is no DOM element with the id userDetail when you invoke document.getElementById("userDetail");.
To verify this, you could log the value of targetDiv immediately after your assignment:
const targetDiv = document.getElementById("userDetail");
console.log(targetDiv); // null
Why is <div id="userDetail"> not a DOM element?
Because it is a part of a template within a script tag. The type="text/x-handlebars-template" attribute you have added to your script block is basically telling the browser to ignore what it contains. This is what allows you to add arbitrary content, like the mustaches understood by the Handlebars library. For more on this: see Explanation of <script type = "text/template"> ... </script>
In order for your code to reference the DOM element with id userDetail, you will need to get it from the DOM after you have injected your template-rendered HTML into document - ie., after you set the innerHTML of #test to userData:
let targetDiv = null;
fetch("https://5dc588200bbd050014fb8ae1.mockapi.io/assessment")
.then(response => response.json())
.then((data) => {
var userData = template({ usersList: data })
document.getElementById('test').innerHTML = userData;
targetDiv = document.getElementById("userDetail");
}).catch((error) => {
console.log(error)
})
I have created a fiddle for your reference.
Additionally, even with this fix, I think you are going to find that your code does not work as you intend. It looks like you want handleClick to toggle a sibling <div> - and that this should be the effect for each <li> in your <ul>. However, your document.getElementById("userDetail") will return only the first element with id userDetail, so no matter which "Detail" <button> is clicked, only the first <li>'s detail will be toggled. You will need to find a way to specify to your handler which detail to toggle.

How to execute function with arguments, inside another function with Javascript?

i am trying to create simple app using Jquery, but I am stuck, i have two basic functions, first which holds the event, and second function, where i want to call first function, code here:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<button id="test" onclick="funct1(event,id)">clcik1</button>
<button id="test2" onclick="mySecondFunction()">clcik2</button>
<script>
const funct1 = function myFunction(event,id) {
alert(event.target.id);
};
function mySecondFunction(){
return funct1()
}
</script>
</body>
</html>
problem is, first function holds (event and id), Accordingly when i call this function into my second function it throwing errors. I want, when i click second button executes first function... any solutions?
You should pass the arguments to mySecondFunction in onClick and in the js you should take it in mySecondFunction and pass it to funct1. Like this:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<button id="test" onclick="funct1(event,id)">clcik1</button>
<button id="test2" onclick="mySecondFunction(event,id)">clcik2</button>
<script>
const funct1 = function myFunction(event,id) {
alert(event.target.id);
};
function mySecondFunction(event,id){
return funct1(event,id)
}
</script>
</body>
</html>
you need to pass the arguments into your second function:
const funct1 = function myFunction(event,id) {
alert(event.target.id);
};
function mySecondFunction(e, id){
return funct1(e, id)
}
and on the the button
<button id="test2" onclick="mySecondFunction(event, id)">clcik2</button>
Something like this ?

Print the arguments inside a handler function

Passing parameters on JQuery .trigger
The passed arguments are unable to display,
I get undefined even if the arguments are passed. How do I alert the passed arguments when a button is clicked.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<script>
$(document).ready(function(){
$("#btn1").on('click', function(event, one, two) {
alert(one)
});
});
$("#btn1").trigger('click', [1, 2]);
</script>
<button id="btn1">Click here to display args passed</button>
</body>
</html>
you can do it by bellow code.
$(document).ready(()=>{
$("#myBtn").on('click',{ extra : 'you parameter value' }, function(event) {
var data = event.data;
myFunction(data.extra);
});
})
function myFunction(parameter)
{
alert(parameter)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="myBtn">Button</button>

Why in button tag onclick=methodname is not giving output but onclick=operation gives output

In the below code if I change background color of Submit button with onclick="document.getElementById('s').style.background='green'" then it changes perfectly but if I do it with function call then it doesn't work which I tried for Clear button. I have commented the functions. Answer me if you have any solution for this.
function open() {
x = document.getElementById('s');
x.style.background = "green";
}
function close() {
document.getElementById('c').style.background = "red";
}
<!DOCTYPE html>
<html>
<head>
<title>Events-code with me</title>
</head>
<body>
<h1>Changing style</h1>
<button id="s" onclick="document.getElementById('s').style.background='green'">Submit</button>
<button id="c" onclick="close()">Clear</button>
</body>
</html>
close() is a method on the window object when you name your function as close and you called on click. the browser engine called the windows close() method, not your close method. A simple way to solve this is to rename your function.
function open() {
x = document.getElementById('s');
x.style.background = "green";
}
function closeX() {
document.getElementById('c').style.background = "red";
}
<!DOCTYPE html>
<html>
<head>
<title>Events-code with me</title>
</head>
<body>
<h1>Changing style</h1>
<button id="s" onclick="document.getElementById('s').style.background='green'">Submit</button>
<button id="c" onclick="closeX()">Clear</button>
</body>
</html>
Check out this snippet:
<!DOCTYPE html>
<html>
<head>
<title>Events-code with me</title>
</head>
<body>
<h1>Changing style</h1>
<button id="s" onclick="openX();">Submit</button>
<button id="c" onclick="closeX();">Clear</button>
<script type="text/javascript">
function openX() {
x = document.getElementById('s');
x.style.background = "green";
}
function closeX() {
document.getElementById('c').style.background = "red";
}
</script>
</body>
</html>
Actually when you use open(); and close();, it will call window.open(); and window.close();. In JavaScript, all global variables (like document)and functions(for eg alert()) belongs to window object (as window.documentand window.alert()).
To make those functions work, you must rename them, which I have done above.
The open() method is a default method of JS to opens a new browser window or a new tab, so change it with any other method name, for example
function openModal() {
x = document.getElementById('s');
x.style.background = "green";
}
<button id="s" onclick="openModal">Submit</button>
I'tried ur code with function call i'ts because open() and close() are an inbuilt function in javascript and don't forget to write ur js code in tag :)
Give an another function name instead of open and close

How to pass div ids to javascript at onload?

I have an Html file like this:
<!doctype html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="style/boxClass.css" />
<script type="text/javascript">
/* lightBox class */
function box (id1,id2) {
this.boxBackgroundDiv = document.getElementById (id1);
this.boxWorkAreaDiv = document.getElementById (id2);
}
lightBox.prototype.setBackgroundColor = function(c) {
this.boxBackgroundDiv.style.backgroundColor = c;
alert('Hello back');
};
function init (id1,id2)
{
boxObj = new box (id1,id2);
alert ("Hello");
}
</script>
</head>
<body onload="init('box1','box2')">
<div id="lightbox1" class="boxBackground">I am here</div>
<div id="lightbox2" class="boxWorkArea"><button onclick="boxObj.setBackgroundColor('Red')">I am here</button></div>
</body>
</html>
Now when I call my init function the way it is in this code via it works fine. But if I do as below via window.onload, it does not work. its not able to get the div ids in this case. But I need div ids to crate objs for my class.
<!doctype html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="style/boxClass.css" />
<script type="text/javascript">
/* lightBox class */
function box (id1,id2) {
this.boxBackgroundDiv = document.getElementById (id1);
this.boxWorkAreaDiv = document.getElementById (id2);
}
lightBox.prototype.setBackgroundColor = function(c) {
this.boxBackgroundDiv.style.backgroundColor = c;
alert('Hello back');
};
function init (id1,id2)
{
boxObj = new box (id1,id2);
alert ("Hello");
}
window.onload = init ("box1",box2);
</script>
</head>
<body>
<div id="lightbox1" class="boxBackground">I am here</div>
<div id="lightbox2" class="boxWorkArea"><button onclick="boxObj.setBackgroundColor('Red')">I am here</button></div>
</body>
</html>
Two issues:
1) You are missing quotes around box2 parameter,
2) You are assigning the return value of init function (which here is a void) to window.onload handler.
You should assign the onload handler as below:
window.onload = function(){
init ("box1","box2");
}

Categories