Search code examples
javascriptjqueryrefactoringcode-duplication

Refactoring code - variable scope


I have 3 buttons that concatenate input text differently:

 var myTxtArea = document.getElementById('KWarea');
 myTxtArea.value = myTxtArea.value.replace(/^\s*|\s*$/g, '');
 var lines = $('#KWarea').val().replace(/\*/g, '').split('\n');
 $('#produce').click(function () {
     var endString = "";

     myTxtArea.value = myTxtArea.value.replace(/^\s*|\s*$/g, '');
     var lines = $('#KWarea').val().replace(/\*/g, '').split('\n');
     for (var i = 0; i < lines.length; ++i) {
         endString += '"*' + $.trim(lines[i]) + '*"' + ',' + '"* ' + lines[i] + ' *"' + ',';
         //   console.log(lines[i]);
     }
     var trimmedStr = endString.slice(0, -1);
     $('#result1').html("ctx.keywords MATCHES (" + trimmedStr + ")");
     $('#Strlength').html('Total string length: ' + trimmedStr.length);

 });

 $('#produce2').click(function () {
     var endString = "";
     for (var i = 0; i < lines.length; ++i) {
         endString += '"*' + $.trim(lines[i]) + '*"' + ',';
     }
     var trimmedStr = endString.slice(0, -1);
     $('#result1').html("ctx.keywords MATCHES (" + trimmedStr + ")");
     $('#Strlength').html('Total string length: ' + trimmedStr.length);

 });

 $('#produce3').click(function () {
     var endString = "";
     for (var i = 0; i < lines.length; ++i) {
         endString += '"' + $.trim(lines[i]) + '"' + ',';
     }
     var trimmedStr = endString.slice(0, -1);
     $('#result1').html("ctx.keywords MATCHES (" + trimmedStr + ")");
     $('#Strlength').html('Total string length: ' + trimmedStr.length);

 });

I would like to avoid repeating over and over the following:

  $('#result1').html("ctx.keywords MATCHES (" + trimmedStr + ")");
     $('#Strlength').html('Total string length: ' + trimmedStr.length);

But trimmedStr depends on endString and I can't refactor without ending up with some var undefined

Jsfiddle here

Many thanks


Solution

  • It looks like a little bigger refactoring might be beneficial. Something along these lines?

    function getInput () {
        var lines = $('#KWarea').val().split('\n');
        var plainKeywords = lines.map(function (line) {
            // Match the line for correct input string
            return line.match(/^\s*\**([a-z 0-9]+)\**\s*$/i)[1];  
        }).filter(function (word) {
            // No match -> discard line
            return word !== undefined;
        });
        return plainKeywords;
    }
    
    function getKeywords (type, word) {
        if(type == 1) return ['"*' + word + '*"', '"* ' + word + ' *"'];
        if(type == 2) return ['"*' + word + '*"'];
        return ['"' + word + '"'];
    }
    
    function showKeywords (type) {
        // Comma seperated list of keywords
        var output = getInput().reduce(function (memo, i) {
            return memo.concat(getKeywords(type, i));
        }, []).join(',');
        $('#result1').html('ctx.keywords MATCHES (' + output + ')');
        $('#Strlength').html('Total string length: ' + output.length);
    }
    
     $('#produce').click(showKeywords.bind(null, 1));
     $('#produce2').click(showKeywords.bind(null, 2));
     $('#produce3').click(showKeywords.bind(null, 3));
    

    http://jsfiddle.net/g8rsxmy3/5/