1

I am trying to host my developer profile on GitHub. I have a small javascript typing project I am working on that gets a quote from an API and lets you type the results showing your errors and WPM. It is a little rough right now and certainly needs work but it functions perfectly as is on my local machine. When I uploaded to gitHub though the css and html seemed to have worked fine but the quote and all the javascript functions that load when a new quote is loaded dont seem to work at all.

I am getting the following console error "Uncaught TypeError: Cannot read property 'addEventListener' of null at script.js:16"

I thought the GitHub may be useful aslo https://github.com/nicklandreth73/Nick-Landreth

const randomQuoteApiUrl = 'https://api.quotable.io/random'
const quoteDisplayElement = document.getElementById('quoteDisplay')
const quoteInputElement = document.getElementById('quoteInput')
const timerElement = document.getElementById('timer')
const wpmElement = document.getElementById('wpm')
const errorsElement = document.getElementById('errors')


let errors
let minutes
let words
let wpm
let startTime

// checks at each input and performs neccesary operation
quoteInputElement.addEventListener('input', () => {
    const arrayQuote = quoteDisplayElement.querySelectorAll('span')
    const arrayValue = quoteInputElement.value.split('')

    let correct = true
    arrayQuote.forEach((characterSpan, index) => {
        const character = arrayValue[index]
        if (character == null) {
            characterSpan.classList.remove('correct')
            characterSpan.classList.remove('incorrect')
            correct = false
        }
        else if (character === characterSpan.innerText) {
            characterSpan.classList.add('correct')
            characterSpan.classList.remove('incorrect')
            addLength()
        } else {
            characterSpan.classList.add('incorrect')
            characterSpan.classList.remove('correct')
            correct = false
            removeLength()
        }
    })
    if (correct) renderNewQuote()

})
// gets a new quote from randomQuoteApi
function getRandomQuote() {
    return fetch(randomQuoteApiUrl)
        .then(response => response.json())
        .then(data => data.content)
}
// resets all elements and gets a new quote
async function renderNewQuote() {
    const quote = await getRandomQuote()
    quoteInputElement.maxLength = '1'
    errors = 0
    quoteDisplayElement.innerHTML = ''
    quoteInputElement.value = null
    quote.split('').forEach(character => {
        const characterSpan = document.createElement('span')
        characterSpan.innerText = character
        quoteDisplayElement.appendChild(characterSpan)
    })
    startTimer()
    startTracking()
}
function addLength() {
    quoteInputElement.maxLength = (quoteInputElement.value.length + 1)
}
function removeLength() {
    if (quoteInputElement.maxLength >= 2) {
        quoteInputElement.maxLength = (quoteInputElement.value.length - 1)
    }
    errors++
}

// begins the timer
function startTimer() {
    timerElement.innerText = 0
    startTime = new Date()
    setInterval(() => {
        timerElement.innerText = "Time in seconds: " + parseInt(getTimerTime())
    }, 1000)

}
//gets the timer 
function getTimerTime() {
    return ((new Date() - startTime) / 1000)
}
//begins the tracking of words per minute and errors
function startTracking() {
    wpm = 0
    minutes = (getTimerTime() / 60)
    setInterval(() => {
        words = (quoteInputElement.value.length / 5)
        minutes = (getTimerTime() / 60)
        wpm = (words / minutes)
        wpmElement.innerText = "WPM:" + parseInt(wpm)
        errorsElement.innerText = errors
    }, 100)
}

renderNewQuote()
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <script src="script.js" defer></script>
    <title>Speed Typing</title>
</head>

<body>
    <div class="timer" id="timer"></div>
    <div class="wpm" id="wpm"></div>
    <div class="errors" id="errors"></div>
    <div class="container">
        <div class="quote-display" id="quoteDisplay"></div>
        <textarea id="quoteInput" class="quote-input" maxlength="1" autofocus></textarea>
    </div>
</body>

</html>

2
  • Have you got any errors in the browser console? Like a CORS error? Commented Jan 21, 2020 at 1:04
  • Thanks I didn't think of that. Looks like I did "Uncaught TypeError: Cannot read property 'addEventListener' of null at script.js:16" Commented Jan 21, 2020 at 1:09

1 Answer 1

1

Add you script tag at the bottom of the html page before body tag, or add `defer' in the script tag

The defer attribute is a boolean attribute. When present, it specifies that the script is executed when the page has finished parsing.

<script src="script.js" type="text/JavaScript" defer></script>
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much. It immediately worked with that and considering the error it makes perfect sense to me. I appreciate your time!

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.