0

I have a Lightning-Input-Field with onchange and handleChange method. I dispatch an event to the grandparent component to do some calculations.

1st component

handleOnChange(event){
        this.oldCellValue = this.cellValue;
        this.cellValue = event.target.value;
        this.cellValues = [];
        this.cellValuesForSum = [];
        if(this.cellValue == ""){
            this.cellValues.push({ rowId: this.rowid, columnId: this.columnid, quotep: null });
            this.cellValuesForSum.push({ rowId: this.rowid, columnId: this.columnid, quotep: this.oldCellValue, old : true });
        } else {
            this.cellValues.push({ rowId: this.rowid, columnId: this.columnid, quotep: this.cellValue });
            this.cellValuesForSum.push({ rowId: this.rowid, columnId: this.columnid, quotep: this.cellValue, old : false });
        }

        this.dispatchEvent(new CustomEvent('enablebutton', { bubbles: true, composed: true, detail: this.cellValuesForSum[0] }));

    } 

Parent component

handleDisabled(event) {

        console.log('hereeee    ' + JSON.stringify(this.tantiemesRestants));
        
        var result = this.tantiemesRestants.find(item => item.columnId == event.detail.columnId);

        if (result != undefined && event.detail.old == false) {
            this.tantiemesRestants.find(item => item.columnId == event.detail.columnId).sum = this.tantiemesRestants.find(item => item.columnId == event.detail.columnId).sum - Number(event.detail.quotep);
        }

        if (result != undefined && event.detail.old == true) {
            this.tantiemesRestants.find(item => item.columnId == event.detail.columnId).sum = this.tantiemesRestants.find(item => item.columnId == event.detail.columnId).sum + Number(event.detail.quotep);
        }

        this.disabled = false;
    }

The problem is, since the event is onChange the calculation happens many times (every time the user enters a number).

For example : I want to type 27, the subtraction happens twice : once with 2 and twice with 27.

What can I do to prevent this from happening?

1
  • 6
    Consider using onblur instead so you capture the input when the user clicks or tabs away from the input.
    – Phil W
    Commented Jan 2, 2023 at 15:10

3 Answers 3

2
+25

The normal way I seen this handled is via a short delay - that way, if they keep typing, the counter is reset and only fires once they have stopped typing for what is usually long enough to know they have finished entry e.g.

const DELAY = 200;

handleSearchChange(event) {

        let typedValue = event.target.value;
        let eventsName = event.target.name;

        window.clearTimeout(this.delayTimeout);
       
        this.delayTimeout = setTimeout(() => {
            try {
                //call code, dispatch event etc.
            } catch (err) {
                console.log(err);
            }
        }, DELAY);
    }
1
  • Or, if you really need to prevent someone calling the code before they are ready, I would just make them click a button vs waiting for a lack of input Commented Jun 1, 2023 at 18:41
1

BritishBoyinDC's answer answers your question in a technical sense. This method of handling event only once in a period is known as debounce.

However, to consider your question from a user perspective, we never really know how long a user would take to fully enter their input. If you add a delay too short, you risk the calculation happening multiple times (which is what you are trying to avoid). However, if you add a delay too long, it will be noticeable and users might perceive it as lag or bad performance.

So it comes down to what you really want:

  • If it is okay for the calculation to happen multiple times and you just want to avoid it from happening too many times, then debounce is your answer.

  • If you only want the calculation to happen ONE time, that is, after the user is done with their input, it is best to utilize the onblur event, as suggested by Renato and Phil. Although this may not be the best experience as calculations only occur after focus is removed from the input, it ensures that the calculation only happen once without guessing/predicting user input time, which may vary with different users.

0

This looks like a problem on the order of operations and when exactly you do the assignment. You could do the calculation with the onchange event, nothing wrong with that. But you can't do the assignment of the result to your variable when this event is fired precisely because you don't know yet if the user stopped typing. So ideally you perform the calculation with the onchange event but do the assignment after other event happens (like the onblur event, as pointed out by Phil W).

This way, if you have A as the value, and the user inputs a digit B, your component will calculate A - B and get the result of C correctly. But if the user types a digit D right next, your component should calculate A - BD instead because A has not yet been replaced by the onblur event.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .