简体   繁体   English

无法在状态修改方法(TypeError)中访问状态对象的对象属性

[英]Unable to access object property of state object in state modification method (TypeError)

I'm working on a text analyzer in jQuery that returns word count, unique word count, average word length, and average sentence length. 我正在研究jQuery中的文本分析器,它返回字数,唯一字数,平均字长和平均句子长度。

I had it working (at least halfway, up to the unique word count functionality) before I realized my structure was horrible. 在我意识到我的结构很糟糕之前,我让它工作(至少中途,直到独特的字数统计功能)。 So I refactored it...and now I'm having trouble getting it to work at all. 所以我重构了它......现在我无法让它完全工作。

On line 65, I'm getting TypeError: Cannot read property 'length' of null . 在第65行,我得到TypeError: Cannot read property 'length' of null This is in reference to state.sentences , which when I console.log, I get null . 这是对state.sentences引用,当我在console.log时,我得到null I just noticed that when I type in a full sentence as my input, that doesn't come up (and it logs the sentence correctly), but it's still not rendering the content to the DOM. 我只是注意到当我输入一个完整的句子作为我的输入时,它没有出现(并且它正确地记录了句子),但它仍然没有将内容呈现给DOM。

What am I doing wrong here? 我在这做错了什么? Something about the way I'm trying to access the state object, obviously -- but what, exactly, is beyond me. 关于我试图访问state对象的方式,显然是 - 但究竟是什么,超出了我。

Here is the index.js: 这是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'))
    })
})

And here is the index.html: 这是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>

Thank you! 谢谢!

PS If you have any ideas about structuring the app, all thoughts are welcome; PS如果您对构建应用程序有任何想法,欢迎所有想法; I especially am concerned about the way I'm calling all the functions one after another in the ready function at the end. 我特别关注我在最后的ready函数中一个接一个地调用所有函数的方式。 That seems kinda messy for some reason. 出于某种原因,这似乎有点混乱。

Your problem lies in here: 你的问题在于:

$(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.
}

So, eventually you should use a Id selector: 所以,最终你应该使用Id选择器:

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

As your html element has Id attribute: 由于您的html元素具有Id属性:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM