0

Still learning JS since I'm a noob so bear with me.

I have a web app with 2 circular SVG gauges that currently work and I receive this issue before users log-in.

My Problem: I get "Uncaught TypeError: Cannot read property 'setAttribute' of null" firing off like crazy for pathElementTwo.setAttribute('d', describeArc(26, 0, arcTwo)); in console because the area where that specific arc only needs to load when users log in. This only fires off like crazy in console before login, after login it disappears.

How can I fix this issue so console doesn't fire off like crazy before users log in?

Any help is gladly appreciated. Thanks!

JS

function describeArc(radius, startAngle, endAngle) {
    // Helper function, used to convert the (startAngle, endAngle) arc
    // dexcription into cartesian coordinates that are used for the
    // SVG arc descriptor.
    function polarToCartesian(radius, angle) {
        return {
            x: radius * Math.cos(angle),
            y: radius * Math.sin(angle),
        };
    }

    // Generate cartesian coordinates for the start and end of the arc.
    var start = polarToCartesian(radius, endAngle);
    var end = polarToCartesian(radius, startAngle);

    // Determine if we're drawing an arc that's larger than a 1/2 circle.
    var largeArcFlag = endAngle - startAngle <= Math.PI ? 0 : 1;

    // Generate the SVG arc descriptor.
    var d = [
        'M', start.x, start.y,
        'A', radius, radius, 1, largeArcFlag, 0, end.x, end.y
    ].join(' ');    

    return d;
}

var arc = 0;
var arcTwo = 0;

setInterval(function() {
    // Update the ticker progress.
    arc += Math.PI / 1000;
    arcTwo += Math.PI / 1000;

    if (arc >= 2 * Math.PI) { arc = 0; }
    if (arcTwo >= 2 * Math.PI) { arcTwo = 0; }


    // Update the SVG arc descriptor.
    var pathElement = document.getElementById('arc-path');
    var pathElementTwo = document.getElementById('arc-path-two');

    pathElement.setAttribute('d', describeArc(26, 0, arc));
   pathElementTwo.setAttribute('d', describeArc(26, 0, arcTwo));

    }, 400 / 0)

HTML

<div class="ticker-body">
                <svg viewBox="19, -19 65 35" class="gauge-background" 
fill="none">
                    <circle r="10"/>
                </svg>

                <svg viewBox="-39, -39 700 75" class="gauge" fill="none">
                    <path id="arc-path" transform="rotate(-90)" stroke-
linecap="circle" />
                </svg>
                </div>
                <div class="overlay-collect"></div>
                <div class="hot-offer-btn"></div>

<div class="ticker-body-two">
                        <svg viewBox="4, -19 65 35" class="gauge-background-
two" fill="none">
                            <circle r="10"/>
                        </svg>

                        <svg viewBox="-51, -34 450 75" class="gauge-two" 
fill="none">
                            <path id="arc-path-two" transform="rotate(-90)" 
stroke-linecap="circle" />
                        </svg>
                        </div>
9
  • That error means that getElementById is not returning the object. Could you post your html? And that second argument on setInterval probably shoudn't be a division by 0 Commented Jul 13, 2017 at 17:37
  • please share the html Commented Jul 13, 2017 at 17:37
  • Please post a minimal reproducible example Commented Jul 13, 2017 at 18:33
  • Ask yourself why pathElementTwo doesn't exist yet. Are you waiting till the DOM is ready? If it is an external SVG, are you waiting for it to load before trying to access its DOM? Commented Jul 13, 2017 at 18:36
  • @PaulLeBeau LeBeau I need pathElementTwo to fire off only after users log in not before log in. That's my problem. That area is in a hidden div before login. How can I solve this? Commented Jul 13, 2017 at 18:44

1 Answer 1

2

Basically, you just need to add something to short circuit the build if you aren't ready for it.

One simple way with the code you have would be to just return if !pathElement.

setInterval(function() {
  // Update the SVG arc descriptor.
  var pathElement = document.getElementById('arc-path');
  var pathElementTwo = document.getElementById('arc-path-two');

  if (!pathElement || !pathElementTwo) {
    return; // don't do the rest
  }

  // Update the ticker progress.
  arc += Math.PI / 1000;
  arcTwo += Math.PI / 1000;

  if (arc >= 2 * Math.PI) { arc = 0; }
  if (arcTwo >= 2 * Math.PI) { arcTwo = 0; }

  pathElement.setAttribute('d', describeArc(26, 0, arc));
  pathElementTwo.setAttribute('d', describeArc(26, 0, arcTwo));
}, 400 / 0)

Now, if pathElement or pathElementTwo are null, it'll just return out of the function and stop doing things.

I also pulled the variables up to the top of the function for two reasons.

First, it's just good convention to declare all variables for a scope at the top, for readability and to help avoid potential errors.

The other reason, for this case in particular, is so you can jump out as early as possible. No need to do the other math if we aren't going to be able to do anything with it.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks! Your solution works, however I need 'pathElement.setAttribute('d', describeArc(26, 0, arc));' to run before login. How can I make that happen?
'pathElement.setAttribute('d', describeArc(26, 0, arc));' is where the first svg gauge needs to run before users log-in. How do I get that specific arc now to run without going crazy in console?
if (pathElementTwo == null) solved my issue! Thanks!
crap.. my window was cached and looked like it didn't work :/

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.