What could be causing my JavaScript calculator to malfunction?

I can't seem to figure out why my calculator is malfunctioning and I'm at a loss as to what the issue might be. I even searched on forums like stackoverflow but couldn't find a solution. It seems like there could be an error in the JavaScript code, particularly with the integerDisplay part. Can someone please assist me? I've included my code below. Any help or advice would be greatly appreciated, as I'm completely stumped.

class Calculator {
    constructor(previousOperandTextElement, currentOperandTextElement) {
        this.previousOperandTextElement = previousOperandTextElement
        this.currentOperandTextElement = currentOperandTextElement
        this.clear()
    }

    clear() {
        this.currentOperand = ''
        this.previousOperand = ''
        this.operation = undefined
    }

    delete() {
        this.currentOperand = this.currentOperand.toString().slice(0, -1)
    }

    appendNumber(number) {
        if (number === '.' && this.currentOperand.includes('.')) return
        this.currentOperand = this.currentOperand.toString() + number.toString()     
    }

    chooseOperation(operation) {
        if (this.currentOperand === '') return
        if (this.previousOperand !== '') {
            this.compute()
        }
        this.operation = operation
        this.previousOperand = this.currentOperand
        this.currentOperand = ''
    }

    compute() {
        let computation 
        const prev = parseFloat(this.previousOperand)
        const current = parseFloat(this.currentOperand)
        if (isNaN(prev)  || isNaN(current)) return
        switch (this.operation) {
            case '+':
                computation = prev + current
                break
            case '-':
                computation = prev - current
                break
            case '*':
                computation = prev * current
                break
            case '÷':
                computation = prev / current
                break
            default:
                return
        }
        this.currentOperand = computation 
        this.operation = undefined
        this.previousOperand = ''
    }

    getDisplayNumber(number) {
        const stringNumber = number.toString()
        const integerDigits = parseFloat(stringNumber.split('.')[0])
        const decimalDigits = stringNumber.split('.'[1])
        let integerDisplay
        if (isNaN(integerDigits)) {
            integerDisplay = ''
        } else {
            integerDisplay integerDigits.toLocaleString('en', {
            maximumFractionDigits: 0 })
        }
        if (decimalDigits != null) {
            return `${integerDigits}.${decimalDigits}`
        } else {
          return integerDisplay
        }
    }

    updateDisplay() {
        this.currentOperandTextElement.innerText = 
            this.getDisplayNumber(this.currentOperand)
        if (this.operation != null) {
            this.previousOperandTextElement.innerText = 
                `${this.previousOperand} ${this.operation}`
        } else {
            this.previousOperandTextElement.innerText = '' 
        }
    }
}


const numberButtons = document.querySelectorAll('[data-number]')
const operationButtons = document.querySelectorAll('[data-operation]')
const equalsButton = document.querySelector('[data-equals]')
const deleteButton = document.querySelector('[data-delete]')
const clearAllButton = document.querySelector('[data-clear-all]')
const previousOperandTextElement = document.querySelector('[data-previous-operand]')
const currentOperandTextElement = document.querySelector('[data-current-operand]')

const calculator = new Calculator(previousOperandTextElement, currentOperandTextElement)

numberButtons.forEach(button => {
    button.addEventListener('click', () => {
        calculator.appendNumber(button.innerText)
        calculator.updateDisplay()
    })
})

operationButtons.forEach(button => {
    button.addEventListener('click', () => {
        calculator.chooseOperation(button.innerText)
        calculator.updateDisplay()
    })
})

equalsButton.addEventListener('click', button => {
    calculator.compute()
    calculator.updateDisplay()
})

clearAllButton.addEventListener('click', button => {
    calculator.clear()
    calculator.updateDisplay()
})

deleteButton.addEventListener('click', button => {
    calculator.delete()
    calculator.updateDisplay()
})
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@500&display=swap');
    
        *, *::before, *::after {
            box-sizing: border-box;
            font-family: "Montserrat", sans-serif;
            font-weight: bold;
        }
    
        body {
            padding: 0;
            margin: 0;
            background: linear-gradient(to right, orange, yellow);
        }
    
        .calculator-grid {
            display: grid;
            justify-content: center;
            align-content: center;
            min-height: 100vh;
            grid-template-columns: repeat(4, 100px);
            grid-template-rows: minmax(120px, auto) repeat(5, 100px);
        }
    
        .calculator-grid > button {
            cursor: pointer;
            font-size: 2rem;
            border: 1px solid white;
            outline: none;
            background-color: rgba(255, 255, 255, .75);
        }
    
        .calculator-grid > button:hover {
            background-color: rgba(255, 255, 255, .9);
        }
    
        .span-two {
            grid-column: span 2;
        }
    
        .output {
            grid-column: 1 / -1;
            background-color: rgba(0, 0, 0, .75);
            display: flex;
            align-items: flex-end;
            justify-content: space-between;
            flex-direction: column;
            padding: 10px;
            word-wrap: break-word;
            word-break: break-all;
        }
    
        .output .previous-operand {
            color: rgba(255, 255, 255, .75);
            font-size: 1.5rem;
        }
    .output .current-operand {
        color: white;
        font-size: 2.5rem;
    }
<!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">
    <script src="script.js"></script>
    <title>Calculator</title>
</head>
<body>
    <div class="calculator-grid">
        <div class="output">
            <div data-previous-operand class="previous-operand"></div>
            <div data-current-operand class="current-operand"></div>
        </div>
        <button data-clear-all class="span-two">AC</button>
        <button data-delete>DEL</button>
        <button data-operation>÷</button>
        <button data-number>1</button>
        <button data-number>2</button>
        <button data-number>4</button>
        <button data-operation>*</button>
        <button data-number>4</button>
        <button data-number>5</button>
        <button data-number>6</button>
        <button data-operation>+</button>
        <button data-number>7</button>
        <button data-number>8</button>
        <button data-number>9</button>
        <button data-operation>-</button>
        <button data-number>.</button>
        <button data-number>0</button>
        <button data-equals class="span-two">=</button>
    </div>
</body>
</html>

Answer №1

No event listener is assigned to the button for changing and updating the action method.

It is advised to refer back to the original source.

You can also add events for each control such as *, -, del, etc.

One way to do this is by adding events for buttons with numbers:

for (let i = 0; i < numberButtons.length; i++) {
  const btn = numberButtons[i];
  btn.addEventListener('click', function () {
    calculator.appendNumber(this.innerText)
    calculator.updateDisplay()
  });
}
// It is preferable to add an event for the parent block instead of individually for each child

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for creating a responsive graphic using Bootstrap CSS

I am currently trying to determine how to create individual graphics that can be directly loaded via CSS and made responsive. When I resize the screen, the graphics also adjust accordingly. However, on smaller displays such as mobile phones, the graphics ...

Angular ng-click feature for a dropdown option element

Check out this jsfiddle link: http://jsfiddle.net/cuycbxxp/ Within this dropdown selection, you can choose between names and numbers. Once you select a name and then select a number from the dropdown, a function is executed and an output is displayed in ...

Send both file and model data using AngularJS with FormData

When uploading an image using the file input type along with other user data, my model includes the User class: public class User { public int Id { get; set; } public string Name { get; set; } public int Rollno { get; set; } public byte[] ...

Unexpected CORS error when fetching data with Ajax GET method

I have a question regarding CORS that I hope someone can help me with. I am currently working on an assignment for freecodecamp.com where I need to create a Wikipedia article search based on user input. However, I am struggling to understand how adding hea ...

An effective method for centering text within a parent div using absolute positioning

Looking for some assistance with a coding challenge involving Bootstrap 4. I'm trying to overlap text with an image and align it to the center. Here is the code snippet, any help would be greatly appreciated! HTML <div class="container-fluid f ...

Passing component properties using spaces in VueJS is a simple and effective

I am encountering an issue where I want to pass component props from my view, but I am facing a challenge due to the presence of a space in the value. This causes Vue to return the following error: vendor.js:695 [Vue warn]: Error compiling template: - inva ...

Unexpected Error: Unable to access the 'position' property of an undefined element (D3.JS)

This error occurred when I attempted to fetch JSON data and convert it into a line graph. An unexpected TypeError was thrown: Unable to access the 'position' property of undefined Below is the relevant portion of the JS code: d3.json("../js/ ...

Cannot interact with button through Selenium Python WebDriver

I've been attempting to click a button on a website using Selenium Webdriver in Python, and I'm having some trouble. The button gets highlighted when I try to click on it, but the click() function doesn't actually click it. Here is the HTML ...

The acceleration of the ThreeJS scene intensifies with each passing moment

My friend and I have been collaborating on a university assignment - creating a basic Pacman clone using ThreeJS (which is a requirement). From the start, we've encountered a persistent issue. As our scene continues to run, it progressively speeds up ...

Ensure that the default boolean value is set to false rather than being left as undefined

I have a specific type definition in my code: export type ItemResponse = { .... addedManually: boolean; .... } Whenever I parse a JSON response into this type, I encounter an issue: const response = await fetch( `https://api.com` ); con ...

What is the process for updating the list to retrieve fresh data from the service?

I am currently in the process of calling a web service to retrieve data and display it in a list using directives. Upon loading my fiddle, I successfully load data from a JSON file. The data is displayed correctly in the list. If I click the delete butto ...

Is the neglected property being discarded?

First things first, let's talk about my class: class FavoriteFooBar { ... isPreferred: boolean = false; constructor() { this.isPreferred = false; } } Using a utility library called Uniquer, I arrange a list of FavoriteFooBar instances to pr ...

Encountering a "TypeError: Cannot access the 'state' property of undefined" error while using React's "Map" function

It's clear from the examples below that the first photo functions perfectly when this.state.blabal is NOT located within the map(a, b){blabla} However, as seen in photo2, when I move the functioning block inside the map(a, b){`here!!`} {Object.k ...

Creating a dynamic list structure using <ul> and <li> tags in a CSHTML ASP file

I am aiming to design a visually appealing structure using ul li for categories. Each line of the structure should consist of three elements: <li> <ul class='kwicks kwicks-horizontal'> <li></li><li></l ...

Guide to dynamically loading customer data into an HTML table using JavaScript

I'm looking to populate a table with data on customers including their name, customer ID, and rental cost. Can anyone help me with the JavaScript code needed to insert this data into rows of the table? Your assistance is greatly appreciated. Below is ...

Navigate post Ajax call

When I make an unauthenticated GET request using AJAX, my server is supposed to redirect my application. However, when I receive the redirect (a 303 with /login.html as the location), the response tab in the Firebug console shows me the full HTML of the lo ...

Updating the CSS: Using jQuery to modify the display property to none

I am facing an issue with displaying an element that is defined as display:none in CSS. I tried to use the .show() function in jQuery, but it's not working as expected. Here's the code snippet: CSS .element { position: absolute; display: no ...

Creating a component in Vue to showcase Axios, based on a straightforward example from the documentation

I apologize in advance for what may seem like a trivial question, but I assure you that I have put in a considerable amount of effort to solve this problem without success. In my appService.js file, I am making an API call as follows: import axios from &a ...

Shifting the form to the bottom right corner

Just starting out with HTML5 and CSS, I've been experimenting with different elements. One project I've been working on is a form: <div id="form1"> <form action="demo_form.asp" autocomplete="on" > Departure City & ...

What could be causing my table to malfunction in IE8?

Is it just me, or do my CSS tables not work on IE8? <div class="main-table"> <div class="row"> <a class="secondary-table" href="#"> <div class="secondary-row"> <div class="secondary-cell"> ...