Why won't regex boolean result work to trigger if condition?

The if block won’t run even when the regex.test returns true. Any help greatly appreciated!

const checkNum = () => {
  const regex = /[^0-9]/g;
  const userInput = input.value
  if (input.value === '') {
    alert('Please provide a phone number');
  }
 

  const parsedNum = numberParser(input.value);
  console.log(regex.test(userInput))
  if (regex.test(userInput)) {
    resultsDiv.textContent = 'INVALID'
    console.log('i ran')
  }
}

please include a link to the fCC project or step you are working on so people can understand what requirements you are working to.

^ inside the character class is “not” or “opposite” so are you trying to test for “not numbers” or “numbers”? Because the numberParser function name would seem to suggest you are expecting the input to be a number.

Also, we can’t see what the numberParser function is doing but if it returns NaN that would be true because typeof NaN is "number"

let regex = /[^0-9]/g;
let userInput = 1

console.log(regex.test(userInput)); // false
console.log(regex.test(Number("test"))); // true
console.log(typeof Number("test")); // 'number'

regex = /[0-9]/g;
console.log(regex.test(userInput)); // true
console.log(regex.test(Number("test"))); // false

This is really interesting, I think this because of the “statefulness” of regex that I’m just now learning about. According to the MDN:

JavaScript RegExp objects are stateful when they have the global or sticky flags set (e.g., /foo/g or /foo/y ). They store a lastIndex from the previous match. Using this internally, test() can be used to iterate over multiple matches in a string of text (with capture groups).

So it’s actually saving the place where it left off when you ran your first test (in the console.log), and then when you test again, it tests only from that point on. If you get rid of your console.log(regex.test(user input)) line then the if block will actually run.

I could be wrong because this is brand new info to me and maybe I’m misuderstanding

1 Like

I don’t think that’s the problem, I tweaked the code a bit to run how I would expect and observed the behavior described. If the console.log(regex.test(user input)) line returns true, the following if block with the exact same condition won’t run.

If you can see my above comment and happen to know about that, can you comment if that makes sense?

Adding the code I used for my test

const checkNum = () => {
  const regex = /[^0-9]/g;
  const input = {value: "N"};
  const userInput = input.value
  if (input.value === '') {
    alert('Please provide a phone number');
  }
 

  const parsedNum = Number.parseInt(input.value);
  console.log(userInput);
  if ( regex.test(userInput) ) {
    //resultsDiv.textContent = 'INVALID'
    console.log("i ran");
  }
}

checkNum();

Hello, this is the number validator project in Javascript (course # 2)

Update pending. I seem to have lost the code because I was working in the browser.

Essentially parseNum got me a bunch of string num characters free of any parentheses or spaces. I saw in the tests that stings other then numerics (%&*$#) could be in the test inputs. So, I wanted to only put forward arrays of string number-characters that were free of any other type of character. So if the regex saw anything that wasn’t a string-num-character it would report true, and I could catch it as invalid.

I got the boolean ‘true’ when I tested regex.test(value) with console log. So my assumption was I could use the return value of that expression to trigger the code block, but it doesn’t seem to work.

We do need the full context. All the code and the input it is being tested with.


But I do know about lastIndex. You can reset it on the regex by assigning it 0.

regex.lastIndex = 0

So if doing that between the two calls to test fixes it, then yes, that is the issue.

1 Like

Here is the full context, I reworked the code a bit. I have a regex that works for almost every case. I will probably make a few small functions to help catch any odd extraneous cases.

But the issue remains. I cannot use the boolean returned by REGEX.test(Input) to trigger my if/else if logic! Any help greatly appreciated!

// console.log('script fired')

const input = document.getElementById('user-input');
const checkBtn = document.getElementById('check-btn');
const clearBtn = document.getElementById('clear-btn');
const resultsDiv = document.getElementById('results-div')

const numberParser = (telNum) => {
  const rejectElements = ['(', ')', '-', ' ']
  const numArray = telNum.split('')
  return numArray.filter((el) => !rejectElements.includes(el));
}

const parenthesisCounter = (number) => {
  const parentheses = ['(', ')'];
  const countBin = [];
  number.split('').forEach((char) => {
    if (parentheses.includes(char)) {
      countBin.push(char);
    }
  })
  return countBin.length;
}

const checkNum = () => {
  // const alphaRegex = /[a-z]|[,.<>?!@#$%^&*=+]/g;
  const telRegex = /(?:^)(\s)?(1)?(\s)?(\()?([\d][\d][\d])(\))?(\s)?(-)?([\d][\d][\d])(\s)?(-)?([\d][\d][\d][\d])(?:$)/g;
  const userInput = input.value
  const testResult = telRegex.test(userInput);
  console.log(testResult); /*This will show a return of 'false'*/
/*but the else if logic here will still not work */
  if (userInput === '') {
    alert('Please provide a phone number');
  } else if (telRegex.test(userInput) === false) {
    resultsDiv.textContent = 'INVALID OUH OH'
  }
  
  console.log(parenthesisCounter(userInput))
  const parsedNum = numberParser(input.value);

  if (parsedNum.length < 10) {
    resultsDiv.textContent = 'INVALID'
  }
}

const clearNum = () => {
  resultsDiv.textContent = '';
}

checkBtn.addEventListener('click', checkNum);
clearBtn.addEventListener('click', clearNum);

have you tried resetting lastIndex? using a regex with g has this issue. Or remove g

Why do you need to call test again? You already have the returned boolean value saved to testResult.

Also, it doesn’t seem like your regex is working for all valid numbers.

I’m sorry, I haven’t cleaned the code up yet as I’m still working on it. My main concern is that I can’t get the boolean logic to trigger the conditional code block.

EDIT
I’m not entirely sure why, but it seems to be triggering the block now. I don’t seem to be able to reproduce the situation I was struggling with yesterday.

Out of curiosity, what input(s) were you testing with?

I’m wondering if you’re on to something here. As I’ve just reproduced a strange contradiction in the following code.

There are two console logs in the following code. If you copy and paste the string 5555555555 into the of the html page, it will result in a false test, whereas in the first console log, you will see that the same input results in a true test. What could be causing this contradictory behavior?

I fixed the second console.log to console.log(testResult), but the outcome is the same, it seems to return true for the first regex.test and false for the second regex.test.

// console.log('script fired')

const input = document.getElementById('user-input');
const checkBtn = document.getElementById('check-btn');
const clearBtn = document.getElementById('clear-btn');
const resultsDiv = document.getElementById('results-div')
const telRegex = /(?:^)(\s)?(1)?(\s)?(\()?([\d][\d][\d])(\))?(\s)?(-)?([\d][\d][\d])(\s)?(-)?([\d][\d][\d][\d])(?:$)/g;
//FIRST CONSOLE LOG
const testInput = '5555555555';
console.log(telRegex.test(testInput));

//HELPER FUNCTIONS
const numberParser = (telNum) => {
  const rejectElements = ['(', ')', '-', ' ']
  const numArray = telNum.split('')
  return numArray.filter((el) => !rejectElements.includes(el));
}

const parenthesisCounter = (number) => {
  const parentheses = ['(', ')'];
  const countBin = [];
  number.split('').forEach((char) => {
    if (parentheses.includes(char)) {
      countBin.push(char);
    }
  })
  return countBin.length;
}

//MAIN FUNCTIONS
const checkNum = () => {
  const userInput = input.value;
  const testResult = telRegex.test(userInput);
  const parenthesisCount = parenthesisCounter(userInput) === 2;
  // CONSOLE LOG #2
  console.log(testInput);
  if (testResult === true && parenthesisCount) {
    resultsDiv.textContent = `Valid US number: ${userInput}`;
  } else if (userInput === '') {
    alert('Please provide a phone number');
  } else {
    resultsDiv.textContent = `Invalid US number: ${userInput}`;
  }
};

const clearNum = () => {
  resultsDiv.textContent = '';
}

checkBtn.addEventListener('click', checkNum);
clearBtn.addEventListener('click', clearNum);

Well, my point remains. You only need the result of calling test one time per function call. If you want to log it, capture the return and log that variable. If you want to use the value, use the variable.

I concede that. Thank you!

Solved:

On the first iteration of the problem, it was the global flag being used and running the test twice. As @lasjog pointed out, the best practice is to save the result to a variable, that way you avoid running the test twice.

The second time I had the problem, I mistook it for the same problem described above, but what was really happening was my parenthesis-check logic was triggering the false result, not the regex.

Thanks all for your help!

Also this article helped me too.

1 Like