I have a preexisting form which I’m trying to add jquery validation to containing :
<form id="form" method="POST" action="/title/">
{% csrf_token %}
<input type="hidden" name="id" value="6">
<input type="hidden" name="custom_checkbox_Electronic_Signature_man" value="1">
<p> <span class="style9">First Name </span>
<input type="text" name="first_name" value="" size="20" class="style7"><span class="style9">
Last Name </span>
<input type="text" name="last_name" value="" size="20" class="style7"><span class="style9">
Using the jquery validator plugin, I have added:
$('form').validate({
rules: {
first_name: {
minlen: 3,
maxlength: 15,
required: true
},
last_name: {
minlength: 3,
maxlength: 15,
required: true
},
email: {
required: true,
email: true
},
phone1: {
required: true,
phoneUS: true
},
phone2: {
required: true,
phoneUS: true
},
street: {
required: true
},
city: {
required: true
},
state: {
required: true
},
zip: {
zipcodeUS: true
}
},
highlight: function(element) {
$(element).closest('.style9').addClass('.style13');
//$(element).addClass('.style13');
},
unhighlight: function(element) {
$(element).closest('.style9').removeClass('.style13');
//$(element).removeClass('.style13');
},
errorElement: 'span',
errorClass: 'style13',
errorPlacement: function(error, element) {
if(element.parent('.input-group').length) {
error.insertAfter(element.parent());
} else {
error.insertAfter(element);
}
}
});
I’m getting the error listed above . What am I doing wrong?
При отладке своего кода (обычно на JavaScript) программист может столкнуться с системным сообщением об ошибке «TypeError: Cannot read property ‘xxx’ of undefined». Вместо значения ХХХ указана какая-либо объявленная переменная или свойство объекта, значение которых по различным причинам не задано разработчиком. Ниже разберём, каков перевод данного сообщения, и каково может быть решение возникшей проблемы.

Содержание
- Почему возникает ошибка
- Присвойте начальное значение переменной
- Улучшите связность вашего кода
- Проверьте наличие свойства
- Деструктурируйте доступ к свойствам нужного объекта
- Заключение
Почему возникает ошибка
В переводе данное сообщение выглядит как «Ошибка типа: Не удаётся прочитать неопределённое свойство ХХХ». Поскольку в некоторых языках программирования (в частности, «JavaScript») есть возможность получения доступа к неинициализированным значениям, то это может вызывать появление рассматриваемой мной ошибки.
Что до причин ошибки undefined, то она обычно возникает при отладке какого-либо программного кода, и может быть вызвана следующими факторами:
- Использующиеся в программном коде переменная не была инициализирована (переменной не присвоено значение);
- Была осуществлена попытка доступа к отсутствующему свойству объекта;
- Была попытка получить доступ к отсутствующему элементу массива.
Давайте разберёмся, как исправить данную ошибку при написании вашего кода.

Читайте также: Failed to execute ‘replaceChild’ on ‘Node’ на JavaScript – как исправить.
Присвойте начальное значение переменной
Наиболее очевидным способом исправить ошибку «TypeError: Cannot read property ‘xxx’ of undefined» является присвоение переменной начального значения. Чем меньше такая переменная пребывает в неинициализированном состоянии – тем будет лучше. В идеале лучше сразу же присвоить значение «Variable» = «начальное значение» (‘initial’), хотя далеко не всегда специфика вашего кода может предполагать указанный вариант.
Улучшите связность вашего кода
Термин «связность» в нашем контексте характеризует уровень взаимосвязанности элементов разрабатываемого вами модуля (пространства имён, метода, класса, блока кода). Как известно, существуют два типа связности, а именно сильная и слабая связность. Использование сильной связности предполагает фокусировку элементов модуля лишь на одной задаче. Потому для извлечения выгоды из сильной связности, необходимо держать используемые переменные поближе к блоку кода, в работе которого они используются.
К примеру, вместо блока кода:

будет оптимальнее переместить переменные поближе к месту их применения:

Улучшение связности позволит избежать появление ошибки «Cannot read property ‘xxx’ of undefined» при отладке вашего кода.
Проверьте наличие свойства
В языке Javascript имеются ряд инструментов, позволяющих определить, имеет ли необходимый нам объект какое-либо свойство:
В частности, это:
- typeof obj.prop !== ‘undefined’ — данный инструмент позволяет проверить тип значения свойства;
- obj.prop !== undefined — этот инструмент позволяет сравнить объект непосредственно с undefined;
- ‘prop’ in obj позволяет проверить объект на наличие его собственного или полученного свойства;
- И obj.hasOwnProperty(‘prop’) позволяет проверить объект на наличие его собственного свойства.
В этом и схожих случаях рекомендуется использовать оператор in, который обладает простым и удобным синтаксисом. Наличие оператора in демонстрирует желание проверить, имеет ли объект нужное свойство без обращения к фактическому значению данного свойства.
Деструктурируйте доступ к свойствам нужного объекта
Деструктурирование нужного объекта позволяет непосредственно извлекать значения свойства объекта в переменные или, если такое свойство не существует, устанавливать значение по дефаулту. Такой вариант позволяет исключить прямой контакт с undefined.
Извлечение свойств теперь выглядит примерно так:

Деструктурирование хорошо, когда можно указать значение по умолчанию, и это значение будет возвращено при попытке доступа к отсутствующему свойству. В конечном счёте, благодаря деструктурированию вы сможете избежать появления undefined и всех сопутствующих проблем.
Это интересно: что означает «JavaScript error: Mutations are not initialized.
Заключение
В нашей статье мы разобрали, почему появляется ошибка «TypeError: Cannot read property ‘xxx’ of undefined», как она переводится и как от неё можно избавиться. Во избежание возникновения данной ошибки присвойте начальное значение соответствующей переменной. Это позволит избежать появления рассмотренной выше дисфункции при отладке вашего кода.
Допустим, вы делаете страницу с формой и полем ввода:
<form name="myform">
<input name="myinput" value="10" />
</form>
Нужно, чтобы скрипт нашёл эту форму, достал из неё значение поля ввода и вывел его на экран. Вы пишете скрипт и оформляете его как отдельный файл, который подключаете в разделе head:
<script>
var str = '';
for(i=0; i < document.myform.elements.length; i++){
str += document.myform.elements[i].name +
'=' + encodeURIComponent(document.myform.elements[i].value) +
(i == document.myform.elements.length -1 ? '' : '&');
}
alert(str);
</script>
Этот скрипт должен быть правильным. При тестировании внутри консоли он делает именно то, что нужно. Но после запуска скрипт падает с ошибкой:
❌ Uncaught TypeError: Cannot read property
Это означает: «Вы пытаетесь прочитать у объекта какое-то свойство, но я не могу его найти, а значит, не могу и прочитать то, чего нет».
Странно, ведь вы уверены, что у этого объекта такое свойство точно есть, и вы сто раз так уже делали.
Всё так и одновременно не так.
Что делать с ошибкой Uncaught TypeError: Cannot read property
Эта ошибка чаще всего происходит, когда вы обращаетесь к свойствам объекта раньше, чем объект готов:
- Скорее всего, объект ещё не загрузился.
- Может быть, этот объект должен появиться на странице по скрипту, который ещё не выполнился.
- Допущена опечатка в названии объекта, поэтому при обращении к нему скрипт его не находит.
Наш случай — первый и самый распространённый: мы вызываем скрипт в разделе <head>, но форма у нас ещё не готова — она банально не загружена в документ, поэтому скрипт не может прочитать свойства несуществующей формы.
Чтобы избавиться от этой ошибки, нужно добавить в вызов скрипта атрибут defer — он заставит скрипт подождать, пока страница загрузится полностью, вместе с формой.
<script defer src="...">
Второй вариант — поместить вызов скрипта сразу после формы, тогда к моменту вызова всё окажется на своих местах и ошибки не будет. Или вообще в конце всего документа.
I can confirm this is still an issue.
I am using webpack 5.30 and vue 2.6.11
I am trying to implement lazy loading on our already existing vue app to reduce our bundle size. Here is how I am importing the component:
const ManageSupport = () => import(/* webpackChunkName: "view-support" */ 'components/helpdesk/view-support')
The chunk is created successfully, based on this webpack output: asset view-support.js 29.4 KiB [emitted] (name: view-support)
When trying to navigate to that route, I keep getting (consistently) the error
`[vue-router] Failed to resolve async component default: TypeError: Cannot read property ‘call’ of undefined
TypeError: Cannot read property ‘call’ of undefined
at webpack_require (main.js:26989)
at Function.fn (main.js:27159)`
A snippet from main.js where the error is thrown:
// Execute the module function
/******/ try {
/******/ var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };
/******/ __webpack_require__.i.forEach(function(handler) { handler(execOptions); });
/******/ module = execOptions.module;
/******/ (error here)execOptions.factory.call(module.exports, module, module.exports, execOptions.require);
/******/ } catch(e) {
/******/ module.error = e;
/******/ throw e;
/******/ }
My webpack configuration:
const webpack = require('webpack');
const { VueLoaderPlugin } = require("vue-loader")
const TerserPlugin = require("terser-webpack-plugin")
const CompressionPlugin = require('compression-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
var FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
const bundleOutputDir = './wwwroot/dist';
module.exports = (env) => {
const isDevBuild = env.prod != 'true';
console.log("Starting webpack " + (isDevBuild ? "Dev" : "Prod") + " Build (main.js)")
return {
mode: isDevBuild ? 'development' : 'production',
target: isDevBuild ? false : ['web', 'es5'],
entry: './ClientApp/boot-app.js',
output: {
path: path.resolve(__dirname, bundleOutputDir),
filename: '[name].js',
publicPath: '/dist/'
},
resolve: {
alias: {
'vue$': 'vue/dist/vue',
'components': path.resolve(__dirname, './ClientApp/components'),
'views': path.resolve(__dirname, './ClientApp/views'),
'utils': path.resolve(__dirname, './ClientApp/utils')
},
extensions: ["*", ".js", ".vue", ".json"]
},
module: {
rules: [
// Vue
{ test: /.vue$/, loader: "vue-loader", exclude: /node_modules/ },
// CSS
{ test: /.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] },
{
test: /.m?js/,
resolve: {
fullySpecified: false
}
},
// JavaScript
{
test: /.js$/, exclude: /node_modules/, loader: 'babel-loader',
exclude: file => (
/node_modules/.test(file) &&
!/.vue.js/.test(file)
)
},
{ test: /.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
],
},
plugins: [
new MiniCssExtractPlugin({ filename: "site.css" }),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: path.join(__dirname, 'wwwroot', 'dist', 'vendor-manifest.json')
}),
new VueLoaderPlugin(),
new FriendlyErrorsWebpackPlugin(),
].concat(
isDevBuild ? [
// Dev-only dependencies
] : [
// Prod-only dependencies
new CompressionPlugin({
filename: '[path][base]',
test: /.(js|css|svg|json)$/,
deleteOriginalAssets: true
})
]),
optimization: isDevBuild ? {} : {
minimize: true,
minimizer: [new TerserPlugin({
test: /.js(?.*)?$/i,
})]
},
cache: true
}
}
My package.json
{
"scripts": {
"build": "cross-env webpack --progress --no-devtool --config webpack.config.js --env prod=true",
"start": "NODE_OPTIONS=--max_old_space_size=4096 webpack serve --progress --hot --hot-only --config webpack.config.js --content-base 'wwwroot' --env prod=false",
"vendor": "webpack --config webpack.config.vendor.js --env prod=false --progress --stats-error-details",
"app": "cross-env NODE_OPTIONS=--max_old_space_size=4096 webpack --progress --config webpack.config.js --env prod=false",
"help": "webpack --help"
},
"dependencies": {
"@babel/plugin-transform-runtime": "^7.13.10",
"@fortawesome/fontawesome-svg-core": "^1.2.28",
"@fortawesome/free-brands-svg-icons": "^5.13.0",
"@fortawesome/pro-light-svg-icons": "^5.13.0",
"@fortawesome/pro-regular-svg-icons": "^5.13.0",
"@fortawesome/pro-solid-svg-icons": "^5.13.0",
"@fortawesome/vue-fontawesome": "^0.1.9",
"@microsoft/signalr": "=3.1.6",
"axios": "^0.21.1",
"core-js": "^2.6.11",
"epsg-index": "^1.0.0",
"font-awesome": "^4.6.3",
"lodash": "^4.17.19",
"moment": "^2.24.0",
"moment-mini": "^2.24.0",
"vue": "^2.6.11",
"vue-router": "^2.1.1",
"vue-template-compiler": "^2.6.11",
"vuex": "^2.1.1",
"vuex-persistedstate": "^2.5.4",
"vuex-router-sync": "^4.0.1"
},
"devDependencies": {
"@babel/core": "^7.13.14",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/preset-env": "^7.13.12",
"babel-loader": "^8.2.2",
"bootstrap": "^3.3.6",
"compression-webpack-plugin": "^7.1.2",
"cross-env": "^3.1.3",
"css-loader": "^5.2.1",
"event-source-polyfill": "^0.0.7",
"friendly-errors-webpack-plugin": "^1.7.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.3.1",
"jquery": "^2.2.1",
"lodash-webpack-plugin": "^0.11.5",
"mini-css-extract-plugin": "^1.4.1",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-loader": "^5.2.0",
"postcss-preset-env": "^6.7.0",
"scope-loader": "^1.0.3",
"spectacle-docs": "^1.0.7",
"style-loader": "^2.0.0",
"url-loader": "^0.5.7",
"vue-loader": "^15.9.6",
"webpack": "^5.30.0",
"webpack-cli": "^4.6.0",
"webpack-dev-server": "^3.11.2",
"webpack-hot-middleware": "^2.12.2"
}
}