0

I'm trying to create a calculator component and it is working, the problem is the numbers are not properly parsed and I'm getting NaN as the response.

Here is the sample output I'm getting :

Result of NaN+NaN is NaN

<template>
    <lightning-card title="Simple Calculator" icon-name="standard:formula">
        <lightning-layout multiple-rows>
            <lightning-layout-item size="12" padding="around-medium">
                <lightning-input type="integer" name ="firstNumber" onchange ={numberChangeHandler}></lightning-input>
            </lightning-layout-item>
            <lightning-layout-item size="12" padding="around-medium">
                <lightning-input type="integer" name ="secondNumber" onchange ={numberChangeHandler}></lightning-input>
            </lightning-layout-item>
            <lightning-layout-item size="12" padding="around-medium">
                <lightning-button-group>
                    <lightning-button label="Add" icon-name="utility:add" icon:position="right" onclick={addHandler}></lightning-button>
                    <lightning-button label="Subtract" icon-name="utility:dash" icon:position="right" onclick={subHandler}></lightning-button>
                    <lightning-button label="Multiply" icon-name="utility:close" icon:position="right" onclick={mutiplyHandler}></lightning-button>
                    <lightning-button label="Divide" icon-name="utility:magicwand" icon:position="right" onclick={divideHandler}></lightning-button>
                </lightning-button-group>
            </lightning-layout-item>
            <lightning-layout-item size="12" padding="around-medium">
                <lightning-formatted-text value={currentResult} ></lightning-formatted-text>
            </lightning-layout-item>
        </lightning-layout>
    </lightning-card>
</template>
import { LightningElement, track } from 'lwc';

export default class SimpleCalculator extends LightningElement {
@track currentResult;

    firstNumber = 0;
    secondNumber = 0;

    numberChangeHandler(event){
        const inputBoxName = event.target.name;
        if(inputBoxName === 'firstNumber'){
            this.firstNumber = parseInt(event.target.name);
        }else if(inputBoxName === 'secondNumber'){
            this.secondNumber = parseInt(event.target.name);
        }
    }

    addHandler(){
        const firstN = parseInt(this.firstNumber);
        const secondN = parseInt(this.secondNumber);

        this.currentResult = 'Result of '+firstN+'+'+secondN+' is '+(firstN+secondN);
    }

    subHandler(){
        const firstN = parseInt(this.firstNumber);
        const secondN = parseInt(this.secondNumber);

        this.currentResult = `Result of ${firstN} - ${secondN} is ${firstN-secondN}`;
    }

    mutiplyHandler(){
        const firstN = parseInt(this.firstNumber);
        const secondN = parseInt(this.secondNumber);

        this.currentResult = 'Result of '+firstN+'x'+secondN+' is '+(firstN*secondN);
    }

    divideHandler(){
        const firstN = parseInt(this.firstNumber);
        const secondN = parseInt(this.secondNumber);

        this.currentResult = `Result of ${firstN} / ${secondN} is ${firstN/secondN}`;
    }
}
4

You're trying to parse the element name, instead of its value, and if you try to parse a string like 'firstNumber' into an integer you'll get NaN.
You should also change the type of your lightning-input to number, integer isn't a valid value. The documentation lists every valid one.
Anyway since the default step is 1, only integers will be valid values.
You can check its validity via event.target.validity.valid.
Moreover, as suggested by sfdcfox, you can avoid the if-else writing this[inputBoxName] = parseInt(event.detail.value).

Change

numberChangeHandler(event) {
    const inputBoxName = event.target.name;
    if(inputBoxName === 'firstNumber'){
        this.firstNumber = parseInt(event.target.name);
    }else if(inputBoxName === 'secondNumber'){
        this.secondNumber = parseInt(event.target.name);
    }
}

To

numberChangeHandler(event){
    if (event.target.validity.valid) {
        const inputBoxName = event.target.name;
        this[inputBoxName] = parseInt(event.detail.value)
    } else {
        // handle the invalid input
    }
}

Making those input-filed required and checking the validity would take care of the NaN you'll get when an user erases the content of that field: parseInt('') returns NaN.

Finally there is no need to parse again those value in addHandler, subHandler, mutiplyHandler and divideHandler

1
  • 4
    P.S. You can write this[inputBoxName] = parseInt(event.detail.value) to avoid the if-else statements.
    – sfdcfox
    Sep 5 at 22:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.