0

I have the below for loops, I have it manytime in my code, with different variables name, I would put it in a function with parameters and call it but it didn't work

for(let i = 0; i < inputs.length - 1; i++){
    if(!nputs[i].value){
        error += inputs[i].getAttribute('test') + " is blank";
        isTrue = false;
    }
}

Here what I did

let y = "";
let z = true;
function test(x,y,z){
    for(let i = 0; i < x.length - 1; i++){
        if(!x[i].value){
            y += x[i].getAttribute('name') + " is blank !";
            z = false;
        }
    }   
}

let error = "";
let isTrue = true;
test(inputs,error,isTrue);

shall I do return in the function? if yes which return should I do?

8
  • You have to return something from the function. Commented Dec 7, 2020 at 14:41
  • 1
    Also your snippets do not contain any inputs Commented Dec 7, 2020 at 14:41
  • 1
    "shall I do return in the function?" - yes, having the function just update an external variable is extremely brittle. Calling the function twice means you might get the wrong result unless you reset the external variable. Also note that z = isTrue doesn't mean that isTrue would be updated. Commented Dec 7, 2020 at 14:41
  • "'It doesn't work' isn't descriptive enough to help people understand your problem. Instead, tell other readers what the expected behavior should be. Tell other readers what the exact wording of the error message is, and which line of code is producing it. Use a brief but descriptive summary of your problem as the title of your question." Commented Dec 7, 2020 at 14:41
  • Is there a reason why you ignore the last inputs element (i < inputs.length - 1)? Commented Dec 7, 2020 at 14:43

2 Answers 2

1
  1. Scope: when you define y and z outside the function (in the global scope presumably) they are different than the y and z defined in the parameter list of the function. The ones in the parameter list only exist within the body of the function. Changing the value of the parameter named y within the function does not change the value of the global variable y. So the simple answer to your question is, yes, you need to return something, since the value of the parameter y is lost when the function is done executing.

  2. Give your variables descriptive names. Let the obfuscator do it's thing later.

function test(x,y,z) -> function valueTest(arr, err, success)

  1. The boolean status and error string are redundant bits of information. If the error string is not empty, then the status is failure. So you don't need to return both a boolean and the string.

  2. The status of the previous test is of no relevance to the next test. Therefore, z or success doesn't have to be passed in to the function each time, as it (or something like it) is really the desired output of the function, and each call of the function can be treated separately. If you want to combine the results from different tests then that should be the concern of whatever is calling this function - see separation of concerns and coupling

The only parameter the function actually needs is the value that is under test (the array).

  1. When you write the function you define the return value, and thus you define how other code can decipher those results. The function itself doesn't have to do all the work of interpreting the results and building the error string. If your return value was just an array of name attribute values (of the elements of the test array that failed), the calling code could still process "success" or "failure". If the return value has one or more elements, or a length > 0 that would indicate failure.

Removing the redundant/unnecessary parameters and information, you'll have a function that looks something like this:

function valueTest(arr) {
    let results = [];

    for (let i = 0; i < arr.length - 1; i++){
        if (!arr[i].value) {
            results.push(arr[i].getAttribute('name'));
        }
    }

    return results;
}

The caller can decipher and build an error message from that. It might make sense for the function to handle some of the additional work by returning <name> is blank! instead of just <name>, and then you just need to join the elements of the array.

...so within the function...

results.push(arr[i].getAttribute('name') + ' is blank!');

...and back in the global scope...

const error = valueTest(inputs).join(" ");
let success = error.length > 0;

5.If you want a running status indicator from different tests, evaluate an individual test's result, then logically AND that with the previous result.

const result1 = valueTest(inputs1).join(' ');
let success = results1.length > 0;
const result2 = valueTest(inputs2).join(' ');
success &= (results2.length > 0);
Sign up to request clarification or add additional context in comments.

Comments

0

Seeing the issues with your code are handled in the comments, I present you a simpler method.

If you count the elements that have the attribute and are not empty and compare it to the length of all the inputs passed you will have a better test

const test = (inputs,attr) => [...inputs]
  .filter(inp => inp.getAttribute(attr) && inp.value.trim() !== "").length === inputs.length;

const istrue = test(document.querySelectorAll("input"),"name")

isTrue will be true if all passed inputs has an attribute called name

You can also do

const elems  = document.querySelectorAll("input[name]")
const isTrue = elems.filter(inp => inp.value.trim() !== "").length === elems.length

4 Comments

Add some description of what you're doing, why you're doing it, and at a level that the poster can understand, and I'll remove the -1.
Presumably the reason this relatively simple question only has 1 answer is because most people realize to give this person any meaningful information they'll have to write a small novel explaining basic concepts. Changing the algorithm to a 1 liner doesn't give the poster any clarity into the question he was originally asking.
Don't get me wrong, it's a nice solution, and for a different question it would be a great answer. The poster is struggling with understanding, scope, pass by reference/value, destructuring or objects maybe. Any/all of those concepts would have to be explained in a decent answer.
@EricLease I saw the comments explained what the issue was with the code posted. So I decided to post a simpler test

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.