Angular2: Невозможно прочитать вызов свойства undefined (при загрузке)

Проверьте обновление внизу!

У меня есть служба, которая выдает ошибку, в то время как приложение загружается. Cannot read property 'call' of undefined. Я использую ng2 2.4.2 и angular-cli 1.0.0-beta.24.

ОШИБКА

Uncaught TypeError: Не удается прочитать свойство "вызов" неопределенного в webpack_require (bootstrap 81b10f8...: 52) в Object.621 (environment.ts: 8) в webpack_require (bootstrap 81b10f8...: 52) в Object.450 (src async: 7) в webpack_require (bootstrap 81b10f8...: 52) в Object.1057 (util.service.ts: 35) в webpack_require (bootstrap 81b10f8...: 52) в webpackJsonpCallback (bootstrap 81b10f8...: 23) на main.bundle.js: 1

Как вы видите, это проблема с сервисом util - это выглядит следующим образом:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Project } from '../datatypes/';
import { Response } from '@angular/http';


@Injectable()
export class UtilService {
    constructor(private router: Router) {}

    public redirectToProject(project: Project) {
        let query = project.ProjectName.split(' ')
            .join('-')
            .concat('-' + project.Id)
            .toLowerCase();
        this.router.navigate(['/project', query]);
    }

    public extractData(res: Response) {
        let body = res.json();
        return body || {};
    }
}

Странно: при проверке исходного файла в chrome он не имеет подсветки синтаксиса, что предполагает синтаксическую ошибку - на мой взгляд, нет.

Обновление 20 января 2017 года

Я обновился до ng2.4.4 и angular-cli 1.0.0-beta26. Проблема все та же. Во время игры Арьян узнал, что он работает с бета-версией 21. Необходимо будет проверить изменения. Проблема теперь не в обслуживании выше, а в файле environment.ts (который имеет все значения по умолчанию).

Ответы

Ответ 1

Наконец, я нашел ответ - работает с beta.32.3. Мы должны использовать эти файлы:

<script type="text/javascript" src="inline.bundle.js"></script>
<script type="text/javascript" src="scripts.bundle.js"></script>
<script type="text/javascript" src="styles.bundle.js"></script>
<script type="text/javascript" src="vendor.bundle.js"></script>
<script type="text/javascript" src="main.bundle.js"></script>

Также важно обновить локальный и глобальный пакет. Обновление на глобальном уровне хорошо описано на странице github. Обновление локально тоже легко - просто обновите зависимость в своем пакете. Json.

Важно: так как beta.29 угловой beta.29 - это пакет @angular/cli, а не angular-cli.

Ответ 2

Я думаю, что это происходит, когда вы вносите изменения в импорт модулей во время выполнения.

Запустите приложение еще раз, используя ng serve и это устранило проблему для меня.

Это также может произойти, когда вы пытаетесь использовать компоненты лениво загруженных модулей в других модулях перед тем, как загружается ленивый модуль, или в подобных подобных сценариях.

Ответ 3

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

При использовании веб-пакета обычный Angular 2 index.html не содержит никаких элементов <style> или <script>, а только <app-root></app-root>. При запуске ng serve или ng build файл улучшается на стороне сервера и добавляет в конец файла что-то вроде следующего:

<script type="text/javascript" src="inline.bundle.js"></script>
<script type="text/javascript" src="polyfills.bundle.js"></script>
<script type="text/javascript" src="styles.bundle.js"></script>
<script type="text/javascript" src="vendor.bundle.js"></script>
<script type="text/javascript" src="main.bundle.js"></script>

... или для ng build --prod:

<link href="styles.d41d8cd98f00b204e980.bundle.css" rel="stylesheet"/>
...
<script type="text/javascript" src="inline.66e3ead788094772ecc4.bundle.js"></script>
<script type="text/javascript" src="polyfills.477266e3ead78809ecc4.bundle.js"></script>
<script type="text/javascript" src="vendor.18c581546c015d1bfc6e.bundle.js"></script>
<script type="text/javascript" src="main.9a5c1002f220245829cd.bundle.js"></script>

Полученный файл HTML на стороне сервера отправляется в браузер. И браузеры будут запускать элементы <script> уже присутствующие в HTML, в том порядке, в котором они встречаются.

Но это отличается при добавлении тех элементов <script> стороне клиента, динамически во время выполнения, которые по умолчанию будут выполняться асинхронно. См. Примечания к "сценариям, вставленным парсером" и "сценариям, вставленным сценариями" на странице сценариев MDN.

В нашем случае мы включаем приложение Angular 2 на страницы нашей CMS. Чтобы избежать необходимости изменять страницу CMS всякий раз, когда мы выпускаем новую версию (которая изменит хэши в именах сгенерированных пакетов), мы добавляем пакеты, используя наш собственный код JavaScript. Для браузера это "скрипты с вставкой скриптов". Чтобы убедиться, что они выполняются в правильном порядке, просто установите для async значение false (настройка defer для меня не сработала):

var script = document.createElement('script');
script.async = false;
script.src = ...

Или, при использовании document.write, убедитесь, что он включает атрибут async="false":

document.write(unescape('%3Cscript async="false" src="..." %3E%3C/script%3E'));

(Интересный факт: учтите, что Chrome 55 и более поздние версии могут пропускать эти сценарии блокировки на медленных соединениях, если они размещены в другом домене.)

Без этого чаще всего все было в порядке вплоть до angular-cli 1.0.0-beta.21, хотя мы иногда видели "Не могу найти переменную: webpackJsonp". Для более поздних версий могут отображаться разные ошибки, в зависимости от того, какой сценарий выполняется первым и какой браузер используется. Подобно:

Cannot read property 'call' of undefined
TypeError: modules[moduleId] is undefined
ReferenceError: Can't find variable: webpackJsonp
TypeError: undefined is not an object (evaluating modules[moduleId].call')
Unable to get property 'call' of undefined or null reference

Также обратите внимание, что vendor.bundle.js и polyfills.bundle.js не использовались в более старых версиях. И сценарии, возможно, должны быть вставлены где-то ниже элемента <app-root>.

Ответ 4

У меня была аналогичная проблема. Я обновил до @angular-cli (1.0.0-rc.2) и @angular/core (2.4.9) и последовал за решением Sandrooco. Однако для работы требуется дополнительный файл polyfills.bundle.js.

<script type="text/javascript" src="inline.bundle.js"></script>
<script type="text/javascript" src="polyfills.bundle.js"></script>
<script type="text/javascript" src="styles.bundle.js"></script>
<script type="text/javascript" src="vendor.bundle.js"></script>
<script type="text/javascript" src="main.bundle.js"></script>

Я надеюсь, что это помогает.

Ответ 5

В моем случае мне нужно было убедиться, что у меня есть теги скриптов в правильном порядке.

  <script type="text/javascript" src="inline.bundle.js"></script>
  <script type="text/javascript" src="polyfills.bundle.js"></script>
  <script type="text/javascript" src="styles.bundle.js"></script>
  <script type="text/javascript" src="scripts.bundle.js"></script>
  <script type="text/javascript" src="vendor.bundle.js"></script>
  <script type="text/javascript" src="main.bundle.js"></script>