Function returning Undefined - Javascript

Asked

Viewed 206 times

0

Hello, I’m beginner in js and I’m having trouble in the following function checkRequired(inputArr), for some reason it returns Undefined. I have tried several ways to find the error using the console.log and making some changes to the code, but was not successful If anyone can help me I’d appreciate it.

function checkRequired(inputArr){

    let isRequired = true;
    
    inputArr.forEach(function(input){
        if(input.value.trim() === ""){
            showError(input, `Esse campo deve ser preenchido`);
            isRequired = false;
            return isRequired;
        }
        else{
            showSuccess(input);
            isRequired = true;
            return isRequired;
        }
    });
}

function addTransaction(e){
    
    e.preventDefault();

    if(checkRequired([text, amount])){
        
        const transaction = {
            id: generateID(),
            text: text.value,
            amount: +amount.value
        }
        transactions.push(transaction);
        if(checkRequired([text, amount]) === undefined){
            addTransactionDOM(transaction);
        }
        updateValues();
        updateLocalStorage();
        
        text.value = "";
        amount.value = "";
    }
}

2 answers

3


forEach serves to do something with each element of an array. This "something" is a callback: a function that is passed as an argument to forEach, and executed for each element of the array.

The return, in case, is within the callback. I mean, this here:

inputArr.forEach(function(input) {
    if (input.value.trim() === "") {
        showError(input, `Esse campo deve ser preenchido`);
        isRequired = false;
        return isRequired;
    } else {
        showSuccess(input);
        isRequired = true;
        return isRequired;
    }
});

It would be equivalent to doing this:

function fazAlgo(input) {
    if (input.value.trim() === "") {
        showError(input, `Esse campo deve ser preenchido`);
        isRequired = false;
        return isRequired;
    } else {
        showSuccess(input);
        isRequired = true;
        return isRequired;
    }
}
for (const input of inputArr) {
    fazAlgo(input);
}

You are calling the function several times (one for each element of the array). The function returns, but its return is ignored (it is not stored anywhere).

And the return of callback is not the return of forEach. Not least because forEach returns nothing (it only serves to execute something on all elements).


From what I understand, you want checkRequired return true if all fields are filled in, and false if any of them - anyone - is empty. Then just do:

function checkRequired(inputArr) {
    for (const input of inputArr) {
        if (input.value.trim() === "") { // se algum campo for vazio, retorna false
            showError(input, `Esse campo deve ser preenchido`);
            return false;
        } else showSuccess(input);
    }
    return true;
}

You walk the fields with for...of, and if any of them are empty, return false (do not need to check the rest).

If you’ve reached the end of for, it is because all are filled, so I can return true.

Of course it can also be done with a for "traditional":

function checkRequired(inputArr) {
    for (let i = 0; i < inputArr.length; i++) {
        let input = inputArr[i];
        if (input.value.trim() === "") { // se algum campo for vazio, retorna false
            showError(input, `Esse campo deve ser preenchido`);
            return false;
        } else showSuccess(input);
    }
    return true;
}

The detail is that the above function is stopped once you find an unfilled field.

But if the idea is to always go through all the fields, showing the success or error message to each of them, just do so:

function checkRequired(inputArr) {
    let required = true;
    for (let i = 0; i < inputArr.length; i++) {
        let input = inputArr[i];
        if (input.value.trim() === "") { // se algum campo for vazio, required é false
            showError(input, `Esse campo deve ser preenchido`);
            required = false;
        } else showSuccess(input);
    }
    return required;
}

Notice that it does not make sense to set required = true within the else. What if the first field is not filled but the second yes? If it had required = true within the else, the function would return true, even having an empty field. The idea is that if you find an empty field, required be it false and do not change any more (just have an empty field for the check to fail). Only if all are filled, the function returns true.

The difference is that within the if no longer has the return, then the function is not interrupted. In this case, messages will be shown for all fields, whether empty or not.

  • Opa hkotsubo, thank you very much for the help. And looking again, really the Return did not belong to the checkRequired function, but rather the callback function. I just took the Return from the callback, put it in the function and got to where I wanted, also tested your solution with the for loop. I do not know what would be the most recommended for this situation, because I do not yet know code refinement. But thank you again.

  • @Marcelocabral If the answer solved your problem, you can accept it, see here how and why to do it. It is not mandatory, but it is a good practice of the site, to indicate to future visitors that it solved the problem. And when I get 15 points, you can also vote in all the answers he found useful. And in this case I find the for simpler and clearer than forEach, because you don’t need a callback and you can do everything in your own loop

0

The value is coming back Undefined because you are not giving return on the function, you put some return but they are returning the value to the callback of the function forEach and its function checkRequired() there is no Return, try this here:

function checkRequired(inputArr){

let isRequired = true;

inputArr.forEach(function(input){
    if(input.value.trim() === ""){
        showError(input, `Esse campo deve ser preenchido`);
        isRequired = false;
        return isRequired
    }
    else{
        showSuccess(input);
        isRequired = true;
        return isRequired;
    }
 });

 return isRequired;
}
  • 1

    Opa Jason Rabelo. Looking again here, the Return did not belong to the function checkRequired(), but to callback, I tested with your code and it worked. Thank you so much for your help

Browser other questions tagged

You are not signed in. Login or sign up in order to post.