/    Sign up×
Community /Pin to ProfileBookmark

JS Error: Uncaught Type: Cannot Read Property RemoveChild of Null

Hi all,

I have created a form that is working beautifully, but serving up an error in the console each time the user backspaces their input field content out and leaves the field empty again.

Here is my code. Can anyone lend some insight as to what I can do to stop the errors in the console?

Thanks in advance!

Robin

[CODE]
var email = document.getElementById(“email”);
email.addEventListener(‘keyup’, validateEmail);
function validateEmail(evt) {
var pattern = /^[a-z0-9]+[.]?[a-z0-9]+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$/; //set the regular expression
var str = document.getElementById(“email”).value; //get the user’s input
var emailVal = document.getElementById(“emailVal”);
if (emailVal) { //if the error message div is already on the page
emailVal.parentNode.removeChild(emailVal); //remove it, to prevent a series of error message divs from accumulating
}

//The next 3 lines appear to be the code in question.

if (str == “”) {//if there is no user input
emailVal.parentNode.removeChild(emailVal);//remove the error message
}

if (pattern.test(str) === false) { //if the string doesn’t match the expression
var elem = document.createElement(“div”); //create a DIV
elem.setAttribute(“id”, “emailVal”); //give it an 1)id, 2)class and 3)message
elem.setAttribute(“class”, “form-error-msg”);
if(window.location.href.indexOf(“/en”) > -1) {
elem.innerHTML = ‘Invalid email.’;
}else{
elem.innerHTML = ‘E-mail inválido’;
}
email.parentNode.appendChild(elem); //add the div with the current error message
}
} //end function
[/CODE]

to post a comment
JavaScript

10 Comments(s)

Copy linkTweet thisAlerts:
@Clock_OutMay 19.2016 — The message appears when the code tries to get the parent of a node that doesn't have one.

Here's where the node is removed from the DOM.

<i>
</i>if (emailVal) {
emailVal.parentNode.removeChild(emailVal);
}


Then the code checks for an empty string and tries to remove the same node a 2nd time.

The error message appears because the node was already removed and no longer has a

parent.

<i>
</i>if (str == "") {
emailVal.parentNode.removeChild(emailVal);
}
Copy linkTweet thisAlerts:
@RobinBauthorMay 19.2016 — Hi Clock Out,

Thanks so much for your reply! I know why it's happening already, though. I just don't know how to fix it. I have tried removing that exact part of my code, changing it, putting it in a different place, and changing from keyup to key press, but to no avail.

Do you have any information on how I can stop this from happening?

Thanks again! I really appreciate your reply!

Robin
Copy linkTweet thisAlerts:
@daveyerwinMay 19.2016 — //The next 3 lines appear to be the code in question.

[COLOR="#FF0000"]//[/COLOR]if (str == "") {//if there is no user input
[COLOR="#FF0000"]//[/COLOR] emailVal.parentNode.removeChild(emailVal);//remove the error message
[COLOR="#FF0000"]//[/COLOR]}
Copy linkTweet thisAlerts:
@RobinBauthorMay 19.2016 — Hi DaveyErwin,

I already tried commenting out the code. It caused the error messages to remain on the page at all times, even when the person backed out his code.

Thanks for the reply, anyway!
Copy linkTweet thisAlerts:
@Clock_OutMay 19.2016 — Check for null in the if statement.

if (str == "" &amp;&amp; emailVal.parentNode !== null) {
emailVal.parentNode.removeChild(emailVal);
}
Copy linkTweet thisAlerts:
@daveyerwinMay 20.2016 — Please try this ...
[CODE]

<body><input id=email><div id=emailVal> </div>

<script>
var email = document.getElementById("email");
email.addEventListener('keyup', validateEmail);
function validateEmail(evt) {

var pattern = /^[a-z0-9]+[.]?[a-z0-9]+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$/; //set the regular expression
var str = document.getElementById("email").value; //get the user's input
var emailVal = document.getElementById("emailVal");
if (emailVal) { //if the error message div is already on the page
emailVal.parentNode.removeChild(emailVal); //remove it, to prevent a series of error message divs from accumulating
}
if (pattern.test(str) === false) { //if the string doesn't match the expression

var elem = document.createElement("div"); //create a DIV
elem.setAttribute("id", "emailVal"); //give it an 1)id, 2)class and 3)message
elem.setAttribute("class", "form-error-msg");

if(window.location.href.indexOf("/en") > -1) {
elem.innerHTML = 'Invalid email.';
}else{
elem.innerHTML = 'E-mail inválido';
}

emailVal=email.parentNode.appendChild(elem); //add the div with the current error message
}
} //end function


</script>
</body>

[/CODE]
Copy linkTweet thisAlerts:
@daveyerwinMay 20.2016 — When you remove emailVal

emailVal still refers to

the removed element NOT

the one you just appended

with the same id so ...

emailVal=email.parentNode.appendChild(elem);

sets emailVal as a refference to

the newly appended element.

The removed element has no parent.
Copy linkTweet thisAlerts:
@KeverMay 21.2016 — If you don't want to show a message when the input is empty you should do the following.
if (emailVal) { //if the error message div is already on the page
emailVal.parentNode.removeChild(emailVal); //remove it, to prevent a series of error message divs from accumulating
}

<i> </i>if (str != '' &amp;&amp; pattern.test(str) === false) { //if the string doesn't match the expression
Copy linkTweet thisAlerts:
@Kevin2May 21.2016 — Unless there's a very compelling reason for doing so, destroying then (re)creating a DIV with its attendant attributes and content on each keystroke seems to me to be a rather inefficient method of displaying a simple "error" message. Consider the following:
[code=html]<input type="email" name="email">
<div id="emailVal" class="form-error-msg"></div>[/code]

var email = document.querySelector("input[name=email]");
email.addEventListener('keyup', function() {
var pattern = /[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,}$/;
var str = email.value;
var emailVal = document.getElementById("emailVal");
if (pattern.test(str) === false) {
if (emailVal.innerHTML == '') { //do only if error does not exist
emailVal.innerHTML = (window.location.href.indexOf("/en") &gt; -1) ? 'Invalid email.' : 'E-mail inválido'; // "shorthand" for if/else
}
}
else {
emailVal.innerHTML = '';
}
});

On a much more basic UX level it's very confusing to have an error message appear when all a user does is type one character in a form field. Even more confusing when s/he can't get rid of it by typing more characters. A better way would be to change the triggering event from a keystroke ([B]keyup[/B], et al) to [B]blur[/B]. Let the user get his/her whole email address in there before validating it. In that case either your original script or my script will work, probably with less code in both cases.

However, if it were my form and in spite of some browser support issues, I'd ditch the script completely and take advantage of HTML 5's input types and other attributes:
[code=html]<input type="email" name="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,}$" required>[/code]
This is 2016 and people know how to type an email address. Or their browser auto-completes/auto-suggests it for them. All you need to do is catch mistakes on submission which is what this does. An extra bonus is that language doesn't matter -- the "error message" is in the user's default browser language: English, Spanish, Swahili, whatever.
Copy linkTweet thisAlerts:
@Kevin2May 22.2016 — In my script above change this line:
if (pattern.test(str) === false) {
to:
if (str != '' &amp;&amp; pattern.test(str) === false) {
Removes the error when the input is empty.

Sorry for the late revision...
×

Success!

Help @RobinB spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 7.20,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ,
analytics: Fullres
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: Anonymous,
tipped: article
amount: 1000 SATS,

tipper: Anonymous,
tipped: article
amount: 1000 SATS,

tipper: @Nanditha,
tipped: article
amount: 1000 SATS,
)...