2017-01-12 14 views
1

私は、単語数、一意の単語数、平均単語長、平均文長を返すjQueryのテキスト解析に取り組んでいます。状態変更メソッド(TypeError)で状態オブジェクトのオブジェクトプロパティにアクセスできません

私は自分の構造が恐ろしいことに気づく前に、(少なくとも途中でユニークな単語数の機能まで)働いていました。だから、私はそれをリファクタリングしました...そして今、私はそれをまったく動作させるのに苦労しています。

オンラインでは、私はTypeError: Cannot read property 'length' of nullを取得しています。これはstate.sentencesを参照していますが、私はconsole.logのときにnullと表示されます。私はちょうど私が入力として完全な文章を入力すると、それが出てこない(そしてそれは文章を正しく記録する)が、DOMにコンテンツをレンダリングしていないことに気づいた。

私はここで間違っていますか?明らかに私がstateオブジェクトにアクセスしようとしていることについて何か - しかし、正確に何が私を超えています。ここで

はindex.jsです:

'use strict' 

// state object 

var state = { 
    text: "", 
    words: [], 
    uniqueWords: [], 
    sentences: [], 
    wordLengths: [], 
    sentenceLengths: [], 
    wordCount: 0, 
    uniqueWordCount: 0, 
    averageWordLength: 0, 
    averageSentenceLength: 0 
} 


//state modification functions 

var getText = function(state) { 
    state.text = $('#user-text').val() 
} 

var getWords = function(state) { 
    state.words = state.text.match(/[^_\W]+/g) 
    //need to also change all uppercase to lowercase 
} 

var getSentences = function(state) { 
    state.sentences = state.text.match(/[^\.!\?]+[\.!\?]+/g) 
} 

var getUniqueWords = function(state) { 
    for (var i = 0; i < state.words.length; i++) { 
     if (state.uniqueWords.indexOf(state.words[i]) < 0) { 
      state.uniqueWords.push(state.words[i]) 
     } 
    } 
} 

var getWordCount = function(state) { 
    state.wordCount = state.words.length 
} 

var getUniqueWordCount = function(state) { 
    state.uniqueWordCount = state.uniqueWords.length 
} 

var getWordLengths = function(state) { 
    for (var i = 0; i < state.words.length; i++) { 
     state.wordLengths.push(state.words[i].length) 
     console.log(state.wordLengths) 
    } 
} 

var getAverageWordLength = function(state) { 
    var sum = state.wordLengths.reduce(function(a, b) { 
     return a + b 
    }, 0) 
    state.averageWordLength = sum/state.wordLengths.length 
} 

var getSentenceLengths = function(state) { 
    for (var i = 0; i < state.sentences.length; i++) { 
     state.sentenceLengths.push(state.sentences[i].length) 
    } 
} 

var getAverageSentenceLength = function(state) { 
    var sum = state.sentenceLengths.reduce(function(a,b) { 
     return a + b 
    }, 0) 
    state.averageSentenceLength = sum/state.sentenceLengths.length 
} 

// render functions 

var renderWordCount = function(state, element) { 
    $("dl").toggleClass('hidden') 
    return element.append(state.wordCount) 
} 

var renderUniqueWordCount = function(state, element) { 
    $("dl").toggleClass('hidden') 
    return element.append(state.uniqueWordCount) 
} 

var renderAverageWordLength = function(state, element) { 
    $("dl").toggleClass('hidden') 
    return element.append(state.averageWordLength) 
} 

var renderAverageSentenceLength = function(state, element) { 
    $("dl").toggleClass('hidden') 
    return element.append(state.averageSentenceLength) 
} 

// event listener functions 

$(function() { 
    $('button').click(function() { 
     event.preventDefault() 
     getText(state) 
     getWords(state) 
     getSentences(state) 
     getUniqueWords(state) 
     getWordCount(state) 
     getUniqueWordCount(state) 
     getAverageWordLength(state) 
     getSentenceLengths(state) 
     getAverageSentenceLength(state) 
     renderWordCount(state, $('.wordCount')) 
     renderUniqueWordCount(state, $('.uniqueWordCount')) 
     renderAverageWordLength(state, $('.averageWordLength')) 
     renderAverageSentenceLength(state, $('.averageSentenceLength')) 
    }) 
}) 

そして、ここではindex.htmlにある:

<!DOCTYPE html> 
<html> 
<head> 
    <title>Text analyzer</title> 
    <meta charset="utf-8"> 

    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css"> 
    <link rel="stylesheet" type="text/css" href="main.css"> 
</head> 
<body> 
    <div class="container"> 
     <main> 
      <h1>Text analzyer</h1> 
      <p>Paste in text below, submit, and get some basic stats back.</p> 
      <form class="js-form"> 
       <div> 
        <label for="user-text">Text to analyze</label> 
        <textarea cols="60" rows="20" id="user-text" name="user-text" placeholder="What have you got to say?" required></textarea> 
       </div> 
       <div> 
        <button type="submit">Analyze it!</button> 
       </div> 
      </form> 

      <dl class="hidden text-report"> 
       <dt>Word count</dt> 
       <dd class="wordCount"></dd> 

       <dt>Unique word count</dt> 
       <dd class="uniqueWordCount"></dd> 

       <dt>Average word length</dt> 
       <dd class="averageWordLength"></dd> 

       <dt>Average sentence length</dt> 
       <dd class="averageSentenceLength"></dd> 
      </dl> 
     </main> 
    </div> 
    <script src="jquery-3.1.1.js"></script> 
<!-- <script src="app.js"></script> --> 
    <script src="index.js"></script> 
</body> 
</html> 

ありがとうございました!

P.S.あなたは、アプリの構造についてのアイデアがあれば、すべての考えを歓迎します。私は特に、最後の準備関数で、すべての関数を次々に呼び出す方法について心配しています。それは何らかの理由でちょっと面倒なようです。

+0

あなたのアプリでは、明らかになったプロトタイプパターンがあなたのケースでは素晴らしい選択肢になるかもしれません。もっと多くの講演はhttps://weblogs.asp.net/dwahl in/techniques-strategies-and-patterns-for-structured- javascript-code-revealing-prototype-pattern –

+0

ありがとう!それは非常に便利に見える...私はできるだけ早くそれを読むよ。 – Alacritas

答えて

0

あなたの問題はここにある:だから

$(function() { 
    $('button').click(function() { 
     event.preventDefault() 
     getText(state) // <---at this point you are passing an object to set the text in. 
     // state object but getText has some-thing which is not correct 
     //.....other too 
    }) 
}) 

var getText = function(state) { 
    state.text = $('user-text').val() // <-----Here `user-text` is not a valid 
    // html element and jquery doesn't recognize it. 
    // So, You should change it to a valid css selector. 
} 

、最終的にあなたはIDセレクタを使用する必要がありますあなたのhtml要素にid属性を持っていたよう

$('#user-text').val() 

を:構造化について

<textarea cols="60" rows="20" 
      id="user-text" 
      name="user-text" 
      placeholder="What have you got to say?" required></textarea> 
+0

ありがとうございます!これを反映するように編集されました。 – Alacritas

関連する問題