.toLowerCase() of undefined failing silently in background - but code still works fine

36
January 04, 2019, at 1:50 PM

Obviously, it's not good to let things fail in the background but it seems like it's the only way to get this example to work consistently. How would I work around this?

Sometimes, I need to check a div with a data-attribute on some pages and add a class if it's a match. Other times, I need to check if the URL contains a string and append it to a header.

On the pages where there is no data-attribute to check, it throws:

scripts.js:88 Uncaught TypeError: Cannot read property 'toLowerCase' of undefined

Since there is no data-attribute to check.

Everything looks like this:

$(window).on("load", function() { 
// highlight relevant menu item 
  if (window.location.href.indexOf("stackoverflow") > -1) { 
    $(".main-header--light").text("STACKOVERFLOW"); 
  } 
  var tagName = $("#content").data("category").toLowerCase(); 
  $(".nav-item").each(function() { 
    var menuItem = $(this).text().toLowerCase(); 
    if (menuItem == tagName) { 
      console.log(this); 
      $(this).addClass("subnav-active"); 
    } 
  }); 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
<h1>HEADER - <span class="main-header--light"></span></h1> 
 
<div id="content"></div> 
<ul> 
<li class="nav-item">11</li> 
<li class="nav-item">2</li> 
<li class="nav-item">34</li> 
<li class="nav-item">44</li> 
</ul>

This code works fine as is and when there is a match in window.location.href.indexOf the header updates and when there is a data-attribute to read it works as well. But right away you can see the next function error out since there is no data-attr to read.

See the full version here:

$(window).on("load", function() { 
// highlight relevant menu item 
  if (window.location.href.indexOf("stackoverflow") > -1) { 
    $(".main-header--light").text("STACKOVERFLOW"); 
  } 
  var tagName = $("#content").data("category").toLowerCase(); 
  $(".nav-item").each(function() { 
    var menuItem = $(this).text().toLowerCase(); 
    if (menuItem == tagName) { 
      console.log(this); 
      $(this).addClass("active"); 
    } 
  }); 
});
.active { 
background-color: red; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
<h1>HEADER - <span class="main-header--light"></span></h1> 
 
<div id="content" data-category="Highlight This Item"></div> 
<ul> 
<li class="nav-item">11</li> 
<li class="nav-item">2</li> 
<li class="nav-item">Highlight This Item</li> 
<li class="nav-item">44</li> 
</ul>

I'm trying to understand what would be the best way to have this work consistently so that there are no errors present. I attempted an if else statement like so:

$(window).on("load", function() { 
// highlight relevant menu item 
  if (window.location.href.indexOf("stackoverflow") > -1) { 
    $(".main-header--light").text("STACKOVERFLOW"); 
  } 
  var tagName = $("#content").data("category").toLowerCase(); 
  $(".nav-item").each(function() { 
    var menuItem = $(this).text().toLowerCase(); 
    if (tagName === "undefined") { 
      return false; 
    }  
    else if (menuItem == tagName) { 
      console.log(this); 
      $(this).addClass("subnav-active"); 
    } else {}; 
  }); 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
<h1>HEADER - <span class="main-header--light"></span></h1> 
 
<div id="content"></div> 
<ul> 
<li class="nav-item">11</li> 
<li class="nav-item">2</li> 
<li class="nav-item">34</li> 
<li class="nav-item">44</li> 
</ul>

Which from what I understand of return: false; and How do I prevent, stop, or kill Javascript function? you can use it to not run a function and in this context, stop it from running the check and throwing the error in console.

What would be the best way around this to have a clean/slate no errors?

Answer 1

So do not do it in one line, break it up into two.

var tagName = $("#content").data("category")
if (tagName) {
  tagName = tagName.toLowerCase();
  $(".nav-item").each(function() {
    ...
  })
}
READ ALSO
Can I receive some data from the entire video and selectively control the rest?

Can I receive some data from the entire video and selectively control the rest?

I want the user to receive some data from the entire video and selectively control the restIs there a way for the browser to handle only the specific buffering of the full video? In other words, is it possible to limit the range of media sources that the browser...

62
JavaScript Back-End Library Options [on hold]

JavaScript Back-End Library Options [on hold]

Working on azure functions to temporarily serve as a back-end api to deliver data to the front-end

53
How to read/write JSON data between files? (Node.Js)

How to read/write JSON data between files? (Node.Js)

I am working on a project which requires writing data to a JSON file from one module and calling it from anotherHowever this does not happen, it returns undefined:1 SyntaxError: Unexpected end of JSON input

57
Efficient algorithm to order objects nested in an array

Efficient algorithm to order objects nested in an array

It seems easy enough but when I think of how I would write it, it turns into some big mess and I want it to be as efficient as possible (within a reasonable amount at least)I also have two questions pertaining to this problem

32