Cannot read property 'length' of null in javascript for loop

33,210

Solution 1

instead of using match function which returns a null if the string doesnt match the provided regex use the test function which returns a true/false and then if you need it you can use the match function.

basically you are performing null.length which is obviously invalid as the match is returning you a null

or you could just perform a null check before you check for the length and just do the regex matching once.

if(linkify!==null && linkify.length!== 0)
{
  //do smthing
}

Solution 2

'linkify' is null when there isn't an 'http://' match in the text, so you need to test for that condition:

if(linkify && linkify.length)
Share:
33,210
tim peterson
Author by

tim peterson

web programming-javascript, php, mysql, css, html-is my thang

Updated on July 09, 2022

Comments

  • tim peterson
    tim peterson almost 2 years

    I'm trying to make a markdown editor like Stack Overflow has.

    I get this error listed in the title if I don't actually type an asterisk AND a http:// containing phrase into the textarea. If I only type an asterisk containing phrase, the error refers to this line: if(linkify.length!==0)

    Here's a jsfiddle to show you what I mean.

    Here's my HTML:

    <textarea></textarea>
    <div></div><button type="button">Markdownify</button>
    

    Here's my JS:

    var val=$('textarea').val(), boldify = val.match(/\*\*[A-Za-z0-9]+\*\*/gim),
    italicify = val.match(/\*[A-Za-z0-9]+\*/gim),linkify = val.match(/http\:\/\/[A-z0-9]+\.[A-z0-9]+/gim);
    
    $(document.body).on('click', 'button', function() {
    
    val=$('textarea').val(), boldify = val.match(/\*\*[A-Za-z0-9]+\*\*/gim),
    italicify = val.match(/\*[A-Za-z0-9]+\*/gim),linkify = val.match(/http\:\/\/[A-z0-9]+\.[A-z0-9]+/gim);
    
    if (boldify.length!== 0){
                for (var i=0; i < boldify.length; i++)  {
                    var boldMatch= boldify[i],  
                    boldReplace = boldMatch.replace(/\*\*[A-z0-9]+\*\*/gim, '<span style="font-weight:bold;color:blue;">'+boldMatch+'</span>'),
                    val = val.replace(boldMatch, boldReplace);     
                }
            val = val.replace(/\*\*/gi, "");
    }
    
    if(italicify.length!== 0){
        for(var j=0; j < italicify.length; j++){
        var italicMatch= italicify[j],
         italicReplace = italicMatch.replace(/\*[A-z0-9]+\*/gim, '<span style="font-style:italic;color:red;">'+italicMatch+'</span>');
        val = val.replace(italicMatch, italicReplace); 
        }
        val = val.replace(/\*/gi, "");
    }
    
    if(linkify.length!== 0){
        for(var k=0; k < linkify.length; k++){
        var linkMatch= linkify[k],
        linkReplace = linkMatch.replace(/http:\/\/[A-z0-9]+\.[A-z0-9]+/gim, '<a href="'+linkMatch+'">'+linkMatch+'</a>');
            val = val.replace(linkMatch, linkReplace);
        }
    }
    
    $('div').html(val);
    });
    

    Any help would be greatly appreciated.

  • tim peterson
    tim peterson about 12 years
    hi Baz1nga, thanks for your help, is there any reason I shouldn't just do what jimw suggested, i.e., if(linkify && linkify.length)? That's less code to write then a test and match combo, right?
  • Baz1nga
    Baz1nga about 12 years
    I did not see that answer and I updated my answer considering the peroformance penalty you pay for running the regex twice..
  • tim peterson
    tim peterson about 12 years
    hi jimw, thanks for your comment. I'll ask the opposite question I asked Baz1nga, which is is his code suggestion somehow "better" than the && condition you suggest? Sorry still learning how to program here...
  • jimw
    jimw about 12 years
    In my opinion there's no great difference, unless this code is particularly important to performance. If it's an event handler being called many times a second, whichever method is faster is better. In a simpler case, use whichever suits you - they'll achieve the same end.
  • tim peterson
    tim peterson about 12 years
    great, yeah i don't envision it being critical, though maybe later I'll change it to a keyup at which point maybe i'll refactor it, thanks again!

Related