0

I am trying to test for a null value after a # in a string. I have tried it various ways but I always get a Cannot read property '1' of null when submitting test data. I have ferreted out the errors I can think of but this one I cannot seem to get around. Please keep in mind I am a beginner at this, I haven't programmed since cobol days and the last time i worked on javascript was in the early 2000s.

//start test data, 5 possible strings that may pass through

elt.message = '#1a' //goes through the script good
elt.message = '#12b' // goes through
elt.message = '#123c' //goes through
elt.message = '' //is ignored
elt.message = '# ' //crashes server

//end test data

//First lets test to see if # is in the message. If true then we will parse it and add it to the database.
var str = elt.message;
var substr = '#';
var vtest = str.indexOf(substr) > -1;
if (vtest == 1){
var Vname = elt.author;
console.log('We tested for # and the value is true');

//extracts the number and the letter after the # from incoming chat messages
var test = elt.message; // replace with message text variable. 
var pstr = test.match(/#(\d{1,3})([a-zA-Z])/);
if (pstr) {
var numbers = pstr[1];
var character = pstr[2];
var chupp = character.toUpperCase(); //Converts the lowercase to uppercase
}

//Tests to see if neither the question number or the possible answer is left out
//if (pstr[1] !== '' && pstr[2] !== ''){ //doesn't work =(
if (pstr[1] !== null && pstr[2] !== null){ //doesn't work either =(

console.log('we processed the numbers after the #sign and assigned the numbers and letter into variables.')
console.log('The question number is: ' + pstr[1]);
console.log('The letter processed is: ' + pstr[2]);

// Grabs the date and converts it into the YYYYMMDD string.
var dobj = new Date();
var dstr = dobj.toString();
var dsplit = dstr.split(' ');
let currentdate = `${dobj.getMonth() < '9' ? `0${dobj.getMonth() + 1}` :
  dobj.getMonth() + 1}`;
  currentdate = `${dsplit[3]}${currentdate}${dsplit[2]}`;
console.log(currentdate)//remove when done

//checks to see what the highest question number is in the database
var sel = con.query("SELECT * FROM questions WHERE ClassID = "+ currentdate + " ORDER BY QuesID DESC LIMIT 1", function (err, result){
    if (err) throw err;
    console.log('Total number of question records: '+result[0].QuesID);
    console.log('the script is querying with' + pstr[1]);
    console.log('the scripts answer letter is ' + pstr[2]);

    if (pstr[2] != '' && pstr[1] <= result[0].QuesID ){
        var query =  con.query("SELECT * FROM questions WHERE ClassID = " + currentdate + " AND QuesID = " + pstr[1], function (err, result) { // Selects the record based on the Date and the question number variables provided above
        if (err) throw err;
        console.log('it got past the test')

    if (result[0].AnsweredFirst === '' && result[0].AnswerLetter === chupp) { //Test to see if the AnsweredFirst is empty and that the Answer letter matchs with whats on file
    console.log('MATCH!');//remove when done

    var sql = "UPDATE questions SET AnsweredFirst = '"+ Vname + "' WHERE ClassID = " + currentdate + " AND QuesID = " + pstr[1]; //Updates the record with the first person who answered the question in the AnsweredFirst field
     con.query(sql, function (err, result) {
      if (err) throw err;
      console.log(Vname + " answered question " + pstr[1] + " First!");
     });
    }
  });
 }
});
} else {
    console.log('Either the question number or the letter was left blank so we are skipping'); //the viewer did not put in a proper number and letter after the # sign
    }
} else {
    console.log('No signs of # so skipping queries') //if there is no # sign the message is not processed 
    };

I added the rest of the script to get a better idea. Messages are passed to the server from a chat client.

I'll give it a try moving the block of code into the first if statement. I know its messy but honestly i am surprised I got this far.

1
  • 1
    If your regular expression doesn't match then pstr will be null, so pstr[1] will give an error. Move those tests inside the existing if(pstr) { ... } block. "a null value after a # in a string" - Strings can't contain embedded null values, unless you are looking for a substring "null". Can you please edit your question to show some example inputs with the corresponding desired outputs? Commented Aug 1, 2017 at 3:07

2 Answers 2

2

var pstr = test.match(/#(\d{1,3})([a-zA-Z])/);

means that if no match is found for your regex, then pstr is null

in that case any index of pstr (like pstr[1], pstr[2]) will throw the error you described:

Cannot read property 'n' of null

Solution:

Before using indexes, check if the variable has a value or not

if(pstr !== null) {
    // do something with pstr[1]
}

Edit:

And as nnnnnn rightly pointed out, you cannot explicitly store a null value in a string.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried that using if (pstr[1] !== null && pstr[2] !== null){ but it wouldn't work.
that's wrong. when your object is null, you cannot read it's property (and compare it with null). You have to check the object itself for null
if(pstr !== null) { // do something with pstr[1] } This worked like a charm! No more crashing, THANK YOU SO MUCH!
0

Look. If your test string did not match your regular expression then pstr assigned to null. Besides in next if condition you tried to check first element of pstr without checking it on null value:

if (pstr[1] !== null && pstr[2] !== null){ //doesnt work either =(

So, I think you need either add pstr!==null in second if or move all condition branch from this if inside then part of previous one if statement.

Comments

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.