Error typeerror cannot read properties of undefined reading length

One of the most common errors we record, “Cannot read properties of undefined (reading ‘length’)”, turned up in our own logs recently while looking into an issue with Microsoft Edge and the Facebook sdk. Let’s dive into this error, what it means, and how to fix it.

One of the most common errors we record, “Cannot read properties of undefined (reading ‘length’)”, turned up in our own logs recently while looking into an issue with Microsoft Edge and the Facebook sdk. Let’s dive into this error, what it means, and how to fix it.

Breaking down the Message

TypeError: Cannot read properties of undefined (reading 'length')

In older browsers, this might also be shown as:

Cannot read property 'length' of undefined

TypeError is a subset of JavaScript Error that is thrown when code attempts to do something that does not exist on the target object.

This message indicates that our code expects to have an object with a length property, but that object was not present. length is commonly used on string and array, but a custom object could also have this property.

This is a blocking error, and script execution will stop when this error occurs.

Understanding the Root Cause

This error can be thrown for a lot of reasons, as it is incredibly common to reference the length property of string or array during everyday development. For example, if we had a function that acts on a string argument, but is called without a string, we would see this error.

function foo(myString) {
  if (myString.length >= 10) {
    // do something
  }
}

foo(); // Whoops! TypeError
undefined passed to string function

In our case, we were intercepting a call to fetch, and we had assumed the url property would be a string.

But, dear developer, it was not always a string. 🤦‍♂️.

We had some code like this that intercepted fetch requests and recorded some metadata if the request was correct. It looked something like this:

ourInterceptedFetch(options) {
  if (options.url.length <= 0) {
    // fail out
  }
}
Defensive checking a string

We were doing appropriate defensive type checking to make sure that the options argument had a valid url property. Unfortunately, fetch also accepts options to be any object with a stringifier: an object with a toString method. Like this:

fetch({
  toString: function() {
    return `https://whatever.com/`;
  }
});
Serializable object passed to fetch

In this case, options.url is undefined, so when we try to check options.url.length, it blows up with our error, “Cannot read property ‘length’ of undefined”. Ugh.

While this may be valid, it is a bit weird, right? We thought so too.

How to Fix It

So how do we fix this and prevent it from happening again?

1. Understand why your object is undefined

Understand why your object is undefined

First and foremost, you need to understand why this happened before you can fix it. You are probably not doing exactly the same thing we are, so the reason your object is undefined may be somewhat different. Consider:

  • Are you relying on a network response to be a certain shape?
  • Are you processing user-input?
  • Is an external function or library calling into your code?

Or maybe its just a logical bug somewhere in your code.

2. Add Defensive Checking

Add Defensive Checking

Anytime you don’t completely control the input into your code, you need to be defensively checking that arguments have the correct shape. API response change, functions get updated, and users do terrible, terrible things.

For instance, if you have a fetch request that receives a JSON response with a foo string property, you might have a defensive check that looks like this:

fetch("https://example.com/api")
  .then(resp => {
    return resp.json();
  })
  .then(json => {
    if (!json || typeof json.foo != 'string') {
      // Record an error, the payload is not the expected shape.
    }
  });
Defensive checking a fetch response

3. Monitor Your Environment

 Monitor Your Environment

You’ll need to make sure that the issue is really fixed and that the problem stops happening. Mistakes happen, APIs change, and users are unpredictable. Just because your application works today, doesn’t mean an error won’t be discovered tomorrow. Tracking when exceptional events happen to your users gives you the context to understand and fix bugs faster. Check out TrackJS Error Monitoring for the fastest and easiest way to get started.

The TypeError: Cannot read property 'length' of undefined is one of the most common type errors in JavaScript. It occurs when the length property is read on an undefined variable.

Error message:

TypeError: Cannot read properties of undefined (reading 'length')

Error Type:

TypeError

What Causes TypeError: Cannot Read Property Length of Undefined

Undefined means that a variable has been declared but has not been assigned a value. In JavaScript, properties and functions can only belong to objects. Since undefined is not an object type, calling a function or a property on such a variable causes the TypeError: Cannot read property 'length' of undefined.

TypeError: Cannot Read Property Length of Undefined Example

Here’s an example of a JavaScript TypeError: Cannot read property 'length' of undefined thrown when the length property is attempted to be read on an undefined variable:

function myFunc(a) {
    console.log(a.length);
}

var myVar;
myFunc(myVar);

Since the variable myVar is declared but not initialized, it is undefined. When it is passed to the myFunc() function, the property length is attempted to be accessed. Since a is undefined at that point, running the code causes the following error:

Uncaught TypeError: Cannot read properties of undefined (reading 'length')

How to Avoid TypeError: Cannot Read Property Length of Undefined

When such an error is encountered, it should be ensured that the variable causing the error is assigned a value. The length property is supported by data types such as arrays and strings. Custom objects can also have this property.

To avoid coming across situations where properties of undefined variables may be accessed accidentally, an if check should be added before dealing with such variables:

if (myVar !== undefined) {
    ...
}

if (typeof(myVar) !== 'undefined') {
    ...
}

Updating the previous example to include an if check:

function myFunc(a) {
    if (a !== undefined) {
        console.log(a.length);
    }
}

var myVar;
myFunc(myVar);

Running the above code avoids the error since the property length is only accessed if a is not undefined.

Track, Analyze and Manage Errors With Rollbar

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing JavaScript errors easier than ever. Sign Up Today!

As a JavaScript developer, I’m sure you’ve encountered the frustrating runtime TypeError Cannot read properties of undefined.  TypeScript gives you two ways of interpreting null and undefined types, also known as Type Check Modes, and one of them can avoid this easily overlooked TypeError.

Until TypeScript 2.0, there was only one type check mode — regular — and it considersnull and undefined as subtypes of all other types. This means null and undefined values are valid values for all types.

TypeScript 2.0 introduced Strict Type Check Mode (also referred to as strict null checking mode). Strict Type Check differs from Regular Type Check because it considers null and undefined types of their own.

I’ll show you how Regular Type Check handles undefined (the same applies to null) and how Strict Type Check prevents you from introducing unwanted behavior in our code, like that infamous TypeError Cannot read properties of undefined.

When undefined becomes a problem

The function translatePowerLevel below takes a number as argument and returns strings one, two, many or it's over 9000!.

function translatePowerLevel(powerLevel: number): string {

if (powerLevel === 1) {
return 'one';
}
if (powerLevel === 2) {
return 'two';
}
if (powerLevel > 2 && powerLevel <= 9000) {
return 'many';
}
if (powerLevel > 9000) {
return 'it's over 9000!';
}
}

However, this code doesn’t handle 0, a valid input — yes, looking at you, Yamcha.

yamcha

Yamcha’s Power Level

When JavaScript reaches the end of a function that has no explicit return, it returns undefined.

The translatePowerLevel function return value is typed explicitly as string, but it is possibly also returning undefined when the argument powerLevel has the value 0. Why is TypeScript not triggering an error?

In Regular Type Check Mode, TypeScript is aware that a function might return undefined. But at the same time, TypeScript infers the return type to be only of type string because TypeScript is widening the undefined type to string type.

As another example, if you assign null or undefined to variables while in Regular Type Check Mode, TypeScript will infer these variables to be of type any.

const coffee = null; 

const tea = undefined;

Interpreting undefined or null as subtypes of all other types can lead to runtime problems. For example, if you try to get the length of the result of translateNumber(0), which is undefined, JavaScript will throw this TypeError at runtime: Cannot read properties of undefined (reading 'length').

const powerLevel = translatePowerLevel(0); // undefined

console.log(powerLevel.length); // Uncaught TypeError: Cannot read properties of undefined (reading 'length')

Unfortunately, TypeScript’s Regular Type Check Mode is not able to alert you to when you may have made that mistake.

Strict Type Check Mode to the Rescue

Strict Type Check Mode changes how TypeScript interprets undefined and null values. But first, lets enable Strict Type Check Mode.

How to Enable Strict Type Check Mode in TypeScript

In the root of your project, there should be a tsconfig.json file. This is the TypeScript’s configuration file and you can read more about it here.

// tsconfig.json example

{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}

Inside compilerOptions property, all we need to do is add the property "strictNullChecks": true.

It will look something like this:

// tsconfig.json

{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": true,
"strictNullChecks": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}

Now that we have switched to Strict Type Check Mode, TypeScript throws this error for translatePowerLevel function: Function lacks ending return statement and return type does not include 'undefined'.

That error message is telling you the function is returning undefined implicitly, but its return type does not include undefined in it.

Awesome! TypeScript is now aware the return type does not match all possible return values, and this could lead to problems at runtime! But how can you match the return type to all possible return values?

You can either add a return statement so the function always returns a string (solution #1), or change the return type from string to string | undefined (solution #2).

Match All Possible Return Values: Solution #1

Adding a return statement so it is always explicitly returning a value — in the code below, it is now returning the string zero.

// Solution #1: add a return statement so it always returns a string

function translatePowerLevel(powerLevel: number): string {
if (powerLevel === 1) {
return 'one';
}
if (powerLevel === 2) {
return 'two';
}
if (powerLevel > 2 && powerLevel <= 9000) {
return 'many';
}
if (powerLevel > 9000) {
return 'it's over 9000!';
}
// new return statement
return 'zero';
}

Match All Possible Return Values: Solution #2

Make the undefined return type explicit so wherever translatePowerLevel is used, you have to handle nullish values as well.

// Solution #2: return type as string | undefined

function translatePowerLevel(powerLevel: number): string | undefined {
if (powerLevel === 1) {
return 'one';
}
if (powerLevel === 2) {
return 'two';
}
if (powerLevel > 2 && powerLevel <= 9000) {
return 'many';
}
if (powerLevel > 9000) {
return 'it's over 9000!';
}
}

If you were to compile the following code again using Solution #2, TypeScript would throw the error Object is possibly 'undefined'.

const powerLevel = translatePowerLevel(0); // undefined

console.log(powerLevel.length); // Object is possibly 'undefined'.

When you choose a solution like Solution #2, TypeScript expects you to write code that handles possible nullish values.

There’s no reason not to use Strict Type Check Mode

Now you understand how TypeScript interprets null and undefined types and how you can migrate your project to Strict Mode.

If you are starting a new project, you should definitely enable Strict Type Check Mode from the beginning. And in case you will migrate from Regular to Strict Type Check, our team can help with strategies to do so in a less painful way.

At Bitovi we highly recommend using — or migrating to — Strict Type Check Mode for Angular application development, as it can help you produce better, more reliable code.

Need more help?

Bitovi has expert Angular consultants eager to help support your project. Schedule your free consultation call to get started. 

The issue happen with v4 version (tested on v4.0.3, v4.0.5 and the latest v4.1.2)

With the same config and code base it compile with no problem in v3.9

Expected behavior:

No such error! No failing at internal level! (Plus it works in v3.9 and not v4)

text should not come as undefined! Or should be handled without problem!

Actual behavior:
In v3.9 the code compile with the same config with no problem! In v4 i get Cannot read property ‘length’ of undefined error! And internal failing!

Through the error stack! i get where the error happened and it was at the function computeLineStarts!
text is coming undefined! i did some console logging! And i got what file was been treated! And what text node were printing! The file is all normal and correct! A comment at the end was the last thing which after it the code fail!

Then i added another instruction after it! (A variable assignment const someVar = '';) and the error went up! The last treated nodes before failing came more up! Here bellow the file at which my console.logging stopped at!

File on which the resolution failed at:

https://gist.github.com/MohamedLamineAllal/472cf2043a100cb03244de5fb1138034

When i added const someVar = ""; at the end! the last treated node was } from

export interface IWebSocketDriver {
  readonly protocol: string;
  readonly readyState: number;
  readonly url: string;
  binaryType: BinaryType;
  readonly CONNECTING: number;
  readonly OPEN: number;
  readonly CLOSING: number;
  readonly CLOSED: number;
  setGetStreamObj: (getStreamObj: () => WebSocket | IWebSocketDriver) => IWebSocketDriver;
  onInit: () => IWebSocketDriver;
  onopen: ((this: IWebSocketDriver, ev: Event) => any) | null;
  onmessage: ((this: IWebSocketDriver, ev: MessageEvent) => any) | null;
  onclose: ((this: IWebSocketDriver, ev: CloseEvent) => any) | null;
  onerror: ((this: IWebSocketDriver, ev: Event) => any) | null;
  close(code?: number, reason?: string): void;
  send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
} // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<!!!!!!!!!!!!!!! here the last treated element

/**
 * THINGS TO DO:
 * =============
 *
 *  decide and define the response output of all the functions
 *
 *  consider a design that add useful information that are exchange platform dependent
 *
 *
 *
 * STREAMS :
 * Need to precise what form the returned object should have
 *
 * ok dodo
 */
const someVar = ''; // <=== added this

How i debugged!?

in tsc.js

ts.stringToToken = stringToToken;
    function computeLineStarts(text) {
        console.log('text: ') // <<<==== here
        console.log(text)
        var result = new Array();
        var pos = 0;

And at

ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
    function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
        console.log('Source file: ') // <<<<<<<<<<<<<<<<<<<<<<<<= here
        console.log(sourceFile.path)
        console.log('================+++>')
        if (includeTrivia === void 0) { includeTrivia = false; }
        return getTextOfNodeFromSourceText(sourceFile.text, node, includeTrivia);
    }

First Compilation execution (original file)

Without adding the last const someVar = '';

https://gist.github.com/MohamedLamineAllal/653fd4f597aa821f416a33e86d4514eb

Second compilation (after adding the last line)

https://gist.github.com/MohamedLamineAllal/022f6f285313aec30b82bb72238bcaeb

Always it fails at computeLineStarts() method! And because text is undefined.

Error stack

TypeError: Cannot read property 'length' of undefined
    at computeLineStarts (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:6528:27)
    at Object.getLineStarts (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:6581:60)
    at getCurrentLineMap (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:81810:59)
    at emitDetachedCommentsAndUpdateCommentsInfo (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:85144:94)
    at emitBodyWithDetachedComments (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:85007:17)
    at emitSourceFile (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:83873:21)
    at pipelineEmitWithHint (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:81887:24)
    at noEmitNotification (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:80586:9)
    at onEmitNode (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:70565:13)
    at onEmitNode (/home/coderhero/.nvm/versions/node/v15.0.1/lib/node_modules/typescript/lib/tsc.js:72333:13)

For the shared links i used typescript Version 4.1.2! Otherwise i tested with v4.0.3 and v4.0.5

tsconfig.json

{
  "compilerOptions": {
    "declaration": true,
    "declarationDir": "./dist",
    "module": "commonjs",
    "noImplicitAny": true,
    "lib": ["ESNext", "DOM"],
    "outDir": "./dist",
    "target": "es6",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "esModuleInterop": true
  },
  "typedocOptions": {
    "mode": "modules",
    "out": "docs"
  },
  "include": ["src/**/*.ts", "src/**/*.json", "test"],
  "exclude": ["node_modules", "dist", "src/**/*.spec.ts", "src/**/*.test.ts"]
}

Related Issues:

  • TypeError: Cannot read property ‘length’ of undefined in computeLineStarts #40747
  • TypeError: Cannot read property ‘length’ of undefined in watch mode and {allowJS: true} #35074

I am trying to read the json document from php and convert it needed in js, but an error occurs. :
cannot read properties of undefined (reading ‘length’)
What went wrong? How can I loop the result below without using length ?

Here’s the code:

What I have tried:

/*php */

$conn = db_connect();
$id = mysqli_fix_string( $conn, $id );

$Json_file = file_get_contents("files/sub/".$id."/".sub.json);
print( $json_file );

/*.js */
$.ajax({ url: "./sub/view_sub.php",
         type:"GET",
         data: { id: id },
         success: function( json ) {
            const result = JSON.parse( json );
            console.log(result.sub)
            console.log(result.sub[1]); // OK result is 'serg' 
            console.log(result.sub[2]); // OK result is 'dgf
            if( result.sub.length > 0 ){   <<== error
                 let i = 0;
                 for( const item of result.sub ){
                     foo_arr[id].input_text(i++, item );
                  }
               }
           }
});
              
// console result
>{1: 'serg', 2: 'dgf', 4: 'dfg ', 6: 'dfge ergre'}  <== console.log(result.sub)
uncaught typeError: Cannot read properties of undefined (reading 'length')


Solution 2

Quote:

This is my result /

console.log(result.sub)
{1: 'serg', 2: 'dgf', 4: 'dfg ', 6: 'dfge ergre'} 

Your result is not an array; it’s an object which happens to have numeric property names.

If you want to iterate over the properties of the object, you can use the Object.keys method[^]:

const subKeys = Object.keys(result.sub);
for (let i = 0; i < subKeys.length; i++) {
    foo_arr[id].input_text(i, result.sub[subKeys[i]]);
}

Comments

Solution 1

Try using:

if( result.length > 0 )

Example:

const fruits = ["Banana", "Orange", "Apple", "Mango"];
let length = fruits.length;

result returns:

4

Comments

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

 

Print

Answers RSS

Top Experts
Last 24hrs This month

CodeProject,
20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8
+1 (416) 849-8900

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

От автора: чтобы вернуть сообщество разработчиков, мы рассмотрели нашу базу данных по тысячам проектов и нашли 10 самых распространённых ошибок в JavaScript. Мы собираемся показать вам, что к ним приводит и как это предотвратить. Если ни одна ошибка JavaScript не встречается в вашем коде, это делает вас лучшим разработчиком.

Поскольку всем управляют данные, мы собрали, проанализировали и оценили первые 10 ошибок JavaScript. Rollbar собирает все ошибки из каждого проекта и суммирует, сколько раз каждая из них возникала. Мы делаем это, группируя ошибки в соответствии с их отпечатками пальцев . В принципе, группируется по две ошибки, если вторая — это просто повторение первой. Это дает пользователям хороший обзор вместо огромной свалки, какую вы видели в файле журнала.

Мы сосредоточились на ошибках, которые скорее всего повлияют на вас и ваших пользователей. Чтобы сделать это, мы оценили ошибки по количеству проектов, испытывающихся в разных компаниях. Если бы мы посмотрели только на общее количество раз, когда произошла каждая ошибка, то клиенты большого объема могли бы подавить набор данных с ошибками, которые не имеют отношения к большинству читателей.

Вот первые 10 ошибок JavaScript:

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

Ошибки были сокращены для удобства чтения. Давайте погрузимся глубже в каждую, чтобы определить, что может вызвать её, и как избежать их появления.

1. Uncaught TypeError: Cannot read property

Если вы разработчик JavaScript, то, вероятно, видели эту ошибку очень много раз. Это происходит в Chrome, когда вы читаете свойство или вызываете метод на неопределенный объект. Это можно очень легко проверить в консоли разработчика Chrome.

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

Это может произойти по многим причинам, но чаще всего это неправильная инициализация состояния при рендеринге компонентов пользовательского интерфейса. Давайте рассмотрим пример того, как это может произойти в реальном приложении. Мы выберем React, но те же принципы неправильной инициализации применимы и к Angular, Vue или любой другой структуре.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

class Quiz extends Component {

  componentWillMount() {

    axios.get(‘/thedata’).then(res => {

      this.setState({items: res.data});

    });

  }

  render() {

    return (

      <ul>

        {this.state.items.map(item =>

          <li key={item.id}>{item.name}</li>

        )}

      </ul>

    );

  }

}

Здесь понимаются две важные вещи:

Состояние компонента (например, this.state ) начинает жизнь как undefined.

Когда вы извлекаете данные асинхронно, компонент будет отображаться как минимум один раз перед загрузкой данных — независимо от того, выбрана ли она в конструкторе componentWillMount или componentDidMount . Когда Quiz отображается впервые, this.state.items не определен. Это, в свою очередь, означает, что ItemList получает элементы как неопределенные, и вы получаете сообщение об ошибке «Uncaught TypeError: Невозможно прочитать карту свойств» в консоли.

Это легко исправить. Самый простой способ: инициализировать состояние с разумными значениями по умолчанию в конструкторе.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

class Quiz extends Component {

  // Added this:

  constructor(props) {

    super(props);

    // Assign state itself, and a default value for items

    this.state = {

      items: []

    };

  }

  componentWillMount() {

    axios.get(‘/thedata’).then(res => {

      this.setState({items: res.data});

    });

  }

  render() {

    return (

      <ul>

        {this.state.items.map(item =>

          <li key={item.id}>{item.name}</li>

        )}

      </ul>

    );

  }

}

Код в вашем приложении может отличаться, но мы надеемся, что дали вам достаточно информации, чтобы исправить или избежать этой проблемы. Если нет, продолжайте читать, потому что далее мы рассмотрим больше примеров связанных с ошибками.

2. TypeError: ‘undefined’ is not an object (evaluating

Эта ошибка возникает в Safari при чтении свойства или вызове метода для неопределенного объекта. Вы можете проверить это в консоли разработчика Safari. Это по сути то же самое, что и вышеприведенная ошибка для Chrome, только Safari использует другое сообщение об ошибке.

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

3. TypeError: null is not an object (evaluating

Это ошибка, которая возникает в Safari при чтении свойства или вызове метода для пустого объекта. Проверить это можно в консоли разработчика Safari.

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

Интересно, что в JavaScript значения null и undefined не совпадают, поэтому мы видим два разных сообщения об ошибках. Undefined обычно является переменной, которая не была назначена, а null означает, что значение пустое. Чтобы убедиться, что они не одно и то же, попробуйте использовать строгий оператор равенства:

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

Один из способов, которым эта ошибка может возникнуть в реальном мире — это попытка использовать элемент DOM в JavaScript перед загрузкой элемента. Это потому, что DOM API возвращает null для ссылок на пустые объекты.

Любой JS-код, который выполняет и обрабатывает элементы DOM, должен выполняться после создания элементов DOM. JS-код интерпретируется сверху вниз, как изложено в HTML. Итак, если перед элементами DOM есть тег, код JS в теге скрипта будет выполняться, когда браузер анализирует HTML-страницу. Вы получите эту ошибку, если элементы DOM не были созданы до загрузки сценария.

В этом примере мы можем решить проблему, добавив прослушиватель событий, который уведомит нас, когда страница будет готова. После addEventListener метод init() может использовать элементы DOM.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<script>

  function init() {

    var myButton = document.getElementById(«myButton»);

    var myTextfield = document.getElementById(«myTextfield»);

    myButton.onclick = function() {

      var userName = myTextfield.value;

    }

  }

  document.addEventListener(‘readystatechange’, function() {

    if (document.readyState === «complete») {

      init();

    }

  });

</script>

<form>

  <input type=«text» id=«myTextfield» placeholder=«Type your name» />

  <input type=«button» id=«myButton» value=«Go» />

</form>

4. (unknown): Script error

Ошибка скрипта возникает, когда ошибка неперехваченного JavaScript пересекает границы домена и нарушает политику перекрестного происхождения. Например, если вы размещаете свой код JavaScript на CDN, любые неперехваченные ошибки (ошибки, которые появляются в обработчике window.onerror, вместо того, чтобы быть пойманным в try-catch) будут переданы как просто «Script error» вместо того, чтобы содержать полезную информацию. Эта мера безопасности браузера предназначена для предотвращения передачи данных по доменам, которые в противном случае не были бы допущены к коммуникации.

Чтобы получить реальные сообщения об ошибках, выполните следующие действия:

1. Отправьте заголовок Access-Control-Allow-Origin

Установка заголовка Access-Control-Allow-Origin в * означает, что к ресурсу можно получить доступ из любого домена. Вы можете заменить * своим доменом, если необходимо: например, Access-Control-Allow-Origin: www.example.com . Если вы используете CDN из-за проблем с кэшированием, которые могут возникнуть, обработка нескольких доменов становится сложной и нельзя не приложить усилий. Подробнее см. здесь.

Вот несколько примеров того, как установить этот заголовок в различных средах:

Apache

В папках, где будут храниться ваши файлы JavaScript, создайте файл .htaccess со следующим содержимым:

Header add AccessControlAllowOrigin «*»

Nginx

Добавьте директиву add_header в блок местоположения, который служит файлам JavaScript:

location ~ ^/assets/ { add_header AccessControlAllowOrigin *; }

HAProxy

Добавьте в ресурс, где будут загружены файлы JavaScript:

rspadd AccessControlAllowOrigin: *

2. Установите crossorigin = «anonymous» в теге скрипта

В HTML-источнике для каждого из сценариев, где вы установите заголовок Access-Control-Allow-Origin, в теге SCRIPT установите crossorigin=»anonymous». Убедитесь, что заголовок отправляется для файла сценария, перед добавлением свойства crossorigin в тег скрипта. В Firefox, если атрибут crossorigin присутствует, но заголовок Access-Control-Allow-Origin отсутствует, сценарий не будет выполнен.

5. TypeError: Object doesn’t support property

Это ошибка, которая возникает в IE при вызове неопределенного метода. Вы можете проверить это в IE Developer Console.

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

Это эквивалентно ошибке «TypeError: ‘undefined’ is not a function» в Chrome. Да, разные браузеры могут иметь разные сообщения для одной и той же ошибки.

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

Это обычная проблема для IE в веб-приложениях, использующих пространство имен JavaScript. Когда это так, проблема в 99,9% случаев— это неспособность IE связать методы в текущем пространстве имен с ключевым словом this. Например, если у вас есть пространство имен имен Rollbar с помощью метода isAwesome. Обычно, если вы находитесь в пространстве имен Rollbar вы можете вызвать метод isAwesome со следующим синтаксисом:

Chrome, Firefox и Opera с радостью согласятся с этим синтаксисом. С другой стороны, IE не станет. Таким образом, самая безопасная ставка при использовании JS namespacing — это префикс с фактическим пространством имен.

6. TypeError: ‘undefined’ is not a function

Это ошибка, возникающая в Chrome при вызове неопределенной функции. Вы можете протестировать это в консоли разработчика Chrome и в Mozilla Firefox.

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

Поскольку на протяжении многих лет методы кодирования JavaScript и шаблоны проектирования становятся все более изощренными, наблюдается соответствующее увеличение распространения областей самореференции в обратных вызовах и закрытиях, которые являются довольно распространенным источником этой путаницы.

Рассмотрим фрагмент кода:

function clearBoard(){

  alert(«Cleared»);

}

document.addEventListener(«click», function(){

  this.clearBoard(); // what is “this” ?

});

Выполнение вышеуказанного кода приводит к следующей ошибке: «Uncaught TypeError: undefined is not function». Причина, по которой вы получаете эту ошибку, заключается в том, что при вызове setTimeout() вы вызываете window.setTimeout(). В результате анонимная функция, передаваемая setTimeout(), определяется в контексте объекта окна, у которого нет clearBoard().

Традиционное решение, совместимое со старым браузером — просто сохранить ссылку на this в переменной, которая затем может быть унаследована закрытием. Например:

var self=this;  // save reference to ‘this’, while it’s still this!

document.addEventListener(«click», function(){

  self.clearBoard();

});

Кроме того, в новых браузерах для передачи правильной ссылки вы можете использовать метод bind():

document.addEventListener(«click»,this.clearBoard.bind(this));

7. Uncaught RangeError: Maximum call stack

Это ошибка, которая возникает в Chrome при нескольких обстоятельствах. Одно из них — когда вы вызываете рекурсивную функцию, которая не завершается. Вы можете протестировать это в консоли разработчика Chrome.

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

Это также может произойти, если вы передадите значение функции, находящейся за пределами допустимого диапазона. Многие функции принимают только определенный диапазон чисел для своих входных значений. Например, Number.toExponential(digits) и N umber.toFixed(digits) принимают цифры от 0 до 20, а Number.toPrecision(digits) принимают цифры от 1 до 21.

var a = new Array(4294967295);  //OK

var b = new Array(1); //range error

var num = 2.555555;

document.writeln(num.toExponential(4));  //OK

document.writeln(num.toExponential(2)); //range error!

num = 2.9999;

document.writeln(num.toFixed(2));   //OK

document.writeln(num.toFixed(25));  //range error!

num = 2.3456;

document.writeln(num.toPrecision(1));   //OK

document.writeln(num.toPrecision(22));  //range error!

8. TypeError: Cannot read property ‘length’

Это ошибка, которая возникает в Chrome из-за свойства длины чтения для неопределенной переменной. Вы можете протестировать это в консоли разработчика Chrome.

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

Обычно вы определяете длину, определенную в массиве, но вы можете столкнуться с этой ошибкой, если массив не инициализирован или если имя переменной скрыто в другом контексте. Давайте рассмотрим эту ошибку на следующем примере.

var testArray= [«Test»];

function testFunction(testArray) {

    for (var i = 0; i < testArray.length; i++) {

      console.log(testArray[i]);

    }

}

testFunction();

Когда вы объявляете функцию с параметрами, эти параметры становятся локальными. Это означает, что даже если у вас есть переменные с именами testArray , параметры с одинаковыми именами внутри функции будут по-прежнему рассматриваться как локальные.

У вас есть два способа решить эту проблему:

1. Удалите параметры в объявлении функции (оказывается, вы хотите получить доступ к тем переменным, которые объявлены вне функции, поэтому вам не нужны параметры для вашей функции):

var testArray = [«Test»];

/* Precondition: defined testArray outside of a function */

function testFunction(/* No params */) {

    for (var i = 0; i < testArray.length; i++) {

      console.log(testArray[i]);

    }

}

testFunction();

2. Вызовите функцию, передав ей массив, который мы объявили:

var testArray = [«Test»];

function testFunction(testArray) {

   for (var i = 0; i < testArray.length; i++) {

      console.log(testArray[i]);

    }

}

testFunction(testArray);

9. Uncaught TypeError: Cannot set property

Когда мы пытаемся получить доступ к неопределенной переменной, она всегда возвращает undefined, а мы не можем получить или установить любое свойство undefined. В этом случае приложение будет выбрасывать “Uncaught TypeError cannot set property of undefined.”

Например, в браузере Chrome:

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

Если объект test не существует, будет выдаваться ошибка: “Uncaught TypeError cannot set property of undefined.”

10. ReferenceError: event is not defined

Эта ошибка возникает при попытке получить доступ к переменной, которая не определена или находится за пределами текущей области. Вы можете легко протестировать её в браузере Chrome.

Топ-10 ошибок JavaScript из 1000+ проектов (и как их избежать)

Если вы получаете эту ошибку при использовании системы обработки событий, убедитесь, что вы используете объект события, переданный в качестве параметра. Старые браузеры, такие как IE, предлагают событие глобальной переменной, но не поддерживаются во всех браузерах. Библиотеки, подобные jQuery, пытаются нормализовать это поведение. Тем не менее, лучше использовать тот объект, который передается в функцию обработчика событий.

document.addEventListener(«mousemove», function (event) {

  console.log(event);

})

Вывод

Мы надеемся, что вы узнали что-то новое и сможете избежать ошибок в будущем или, что это руководство помогло вам решить возникшую проблему. Тем не менее, даже при использовании лучших практик в производстве появляются неожиданные ошибки. Важно иметь видимость ошибок, которые влияют на пользователей, и хорошие инструменты для их быстрого решения.

Rollbar предлагает уникальные возможности для приложений JavaScript, таких как телеметрия, которые сообщают вам, что произошло в браузере пользователя, что приводит к ошибке. Это прозрение, которого у вас нет за пределами локальной консоли разработчика.

Автор: Jason Skowronski

Источник: //rollbar.com/

Редакция: Команда webformyself.

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Смотреть

Понравилась статья? Поделить с друзьями:
  • Error typed files cannot contain reference counted types
  • Error typecheck offendingcommand show
  • Error typecheck offendingcommand makefont
  • Error typecheck offending command setdash
  • Error type smtp