1

EDIT: I tried to apply the fix @Thierry provided in his answer, however I keep getting the same error. I created a repository with the full project (clean with no comments) as it resulted by following the tutorial and after applying @Thierry's fix: https://github.com/dragGH102/angular2-tutorial-part4-test

I am following tutorial for Angular 2 at https://angular.io/docs/ts/latest/tutorial/toh-pt4.html

At the end of part 4 I am getting the following error:

SyntaxError: Unexpected token <(…)Zone.run @ angular2-polyfills.js:1243

I even tried to:

  • copy-paste the Plunkr provided at http://plnkr.co/edit/?p=preview but same error.
  • remove the Promise part (which seems to be the cause of the error based on the stacktrace below)
  • compile TS files myself (instead of letting it do by "npm start")

Error stacktrace

SyntaxError: Unexpected token <(…)
Zone.run    @   angular2-polyfills.js:1243
zoneBoundFn @   angular2-polyfills.js:1220
lib$es6$promise$$internal$$tryCatch @   angular2-polyfills.js:468
lib$es6$promise$$internal$$invokeCallback   @   angular2-polyfills.js:480
lib$es6$promise$$internal$$publish  @   angular2-polyfills.js:451
lib$es6$promise$$internal$$publishRejection @   angular2-polyfills.js:401
(anonymous function)    @   angular2-polyfills.js:123
Zone.run    @   angular2-polyfills.js:1243
zoneBoundFn @   angular2-polyfills.js:1220
lib$es6$promise$asap$$flush @   angular2-polyfills.js:262

Apparently (e.g. angular2: Uncaught SyntaxError: Unexpected token < ) this is due to the browser not find valid JS code due to an error but I can't figure out what's wrong .

Here is my code (also available at http://plnkr.co/edit/Q5F0mV8Hbdcr2rtZUSw5 )

index.html

<html>
<head>
    <title>Angular 2 QuickStart</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">

    <script src="node_modules/es6-shim/es6-shim.min.js"></script>
    <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
    <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>

    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

    <script>
        System.config({
            transpiler: 'typescript',
            typescriptOptions: { emitDecoratorMetadata: true },
            packages: {'app': {defaultExtension: 'ts'}}
        });
        System.import('app/boot')
                .then(null, console.error.bind(console));
    </script>
</head>

<body>
    <my-app>Loading...</my-app>
</body>
</html>

app.component.ts

import {Component, OnInit} from 'angular2/core';
import {Hero} from './hero'; 
import {HeroDetailComponent} from './hero-detail.component'; 
import {HeroService} from './hero.service'; 

@Component({
    selector: 'my-app',
    template:`
      <h1>{{title}}</h1>
      <h2>My Heroes</h2>
      <ul class="heroes">
       <li *ngFor="#hero of heroes"
           [class.selected]="hero === selectedHero"
           (click)="onSelect(hero)">
         <span class="badge">{{hero.id}}</span> {{hero.name}}
       </li>
      </ul>
     <my-hero-detail [hero]="selectedHero"></my-hero-detail>
     `,
     // for the sake of code readibility I removed "styles"
    directives: [HeroDetailComponent], 
    providers: [HeroService], 
})

export class AppComponent implements OnInit {
    title = 'Tour of Heroes'; 
    heroes: Hero[]; 
    selectedHero: Hero; 

    constructor(private _heroService: HeroService) { } 

    getHeroes() {
        this.heroes = this._heroService.getHeroes().then(heroes => this.heroes = heroes);
    }

    ngOnInit() {
        this.getHeroes();
    }

    onSelect(hero: Hero) { this.selectedHero = hero; }

}

boot.ts

import {bootstrap}    from 'angular2/platform/browser' 
import {AppComponent} from './app.component'

bootstrap(AppComponent); 

hero-detail.component.ts

import {Component} from 'angular2/core';
import {Hero} from './hero';

@Component({
    selector: 'my-hero-detail',
    template: `
      <div *ngIf="hero">
        <h2>{{hero.name}} details!</h2>
        <div><label>id: </label>{{hero.id}}</div>
        <div>
          <label>name: </label>
          <input [(ngModel)]="hero.name" placeholder="name"/>
        </div>
      </div>`,
    inputs: ['hero']
})

export class HeroDetailComponent {
    hero: Hero;
}

hero.service.ts

import {Hero} from './hero';
import {HEROES} from './mock-heroes'; 
import {Injectable} from 'angular2/core';

@Injectable() 
export class HeroService { 
    getHeroes() {
        return Promise.resolve(HEROES); 
    }

}

hero.ts

export interface Hero {
    id: number;
    name: string;
}

mock-heroes.ts

import {Hero} from "./hero";

export var HEROES: Hero[] = [
    { "id": 11, "name": "Mr. Nice" },
    { "id": 12, "name": "Narco" },
    { "id": 13, "name": "Bombasto" },
    { "id": 14, "name": "Celeritas" },
    { "id": 15, "name": "Magneta" },
    { "id": 16, "name": "RubberMan" },
    { "id": 17, "name": "Dynama" },
    { "id": 18, "name": "Dr IQ" },
    { "id": 19, "name": "Magma" },
    { "id": 20, "name": "Tornado" }
];
Community
  • 1
  • 1
dragonmnl
  • 14,578
  • 33
  • 84
  • 129

1 Answers1

2

I had a look at your plunkr and the problem comes from this line:

getHeroes() {
    this.heroes = this._heroService.getHeroes().then(heroes => this.heroes = heroes);
}

In fact, you mix two approaches:

  • either you set the promise on a component property and then the async pipe to display data when the promise is resolved

    @Component({
      selector: 'my-app',
      template:`
        <li *ngFor="#hero of heroes">
          (...)
        </li>
      `
    })
    export class AppComponent implements OnInit {
      getHeroes() {
        this.heroes = this._heroService.getHeroes();
      }
    }
    
  • either you call the then method and set the received data when resolving into a component property. In this case, you don't need the async pipe

    @Component({
      selector: 'my-app',
      template:`
        <li *ngFor="#hero of heroes">
          (...)
        </li>
      `
    })
    export class AppComponent implements OnInit {
      getHeroes() {
        this._heroService.getHeroes().then(heroes => this.heroes = heroes);
      }
    }
    

See my updates in a forked plunkr: http://plnkr.co/edit/Rw4kOzKFbVosaoe7dRL1?p=preview.

Otherwise I can't see any error like SyntaxError: Unexpected token <(…) but most of time it's because you try to load a JS file and you get a 404 error...

See this question for more details:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • thanks for your answer Thierry. I will eventually try to debug it later on. Perhaps you can have a look at the repository I created with my full code? https://github.com/dragGH102/angular2-tutorial-part4-test thank you – dragonmnl Mar 10 '16 at 21:12