angular 2 Template parse errors unexpected character EOF

Viewed 11829

I just opened and rerun my angular 2 TS app in visual studio.

Last time I did this it worked without any error I am pretty sure.

Now I get this error in the browser console and the app is not loading completely:

EXCEPTION: Template parse errors:
Unexpected character "EOF" ("
   test

</foot[ERROR ->]"): AppComponent@22:6
angular2.js:23083 EXCEPTION: Template parse errors:
Unexpected character "EOF" ("
   test

</foot[ERROR ->]"): AppComponent@22:6BrowserDomAdapter.logError @ angular2.js:23083
angular2.js:23083 STACKTRACE:BrowserDomAdapter.logError @ angular2.js:23083
angular2.js:23083 Error: Template parse errors:
Unexpected character "EOF" ("
   test

</foot[ERROR ->]"): AppComponent@22:6
    at new BaseException (http://localhost:55555/lib/angular2.js:7351:21)
    at TemplateNormalizer.normalizeLoadedTemplate (http://localhost:55555/lib/angular2.js:20019:15)
    at http://localhost:55555/lib/angular2.js:20008:24
    at Zone.run (http://localhost:55555/lib/angular2-polyfills.js:1243:24)
    at Zone.run (http://localhost:55555/lib/angular2.js:13438:32)
    at zoneBoundFn (http://localhost:55555/lib/angular2-polyfills.js:1220:26)
    at lib$es6$promise$$internal$$tryCatch (http://localhost:55555/lib/angular2-polyfills.js:468:17)
    at lib$es6$promise$$internal$$invokeCallback (http://localhost:55555/lib/angular2-polyfills.js:480:18)
    at lib$es6$promise$$internal$$publish (http://localhost:55555/lib/angular2-polyfills.js:451:12)
    at http://localhost:55555/lib/angular2-polyfills.js:123:10

-----async gap-----
Error
    at _getStacktraceWithUncaughtError (http://localhost:55555/lib/angular2-polyfills.js:2236:29)
    at Zone.fork (http://localhost:55555/lib/angular2-polyfills.js:2285:47)
    at Zone.bind (http://localhost:55555/lib/angular2-polyfills.js:1218:53)
    at bindArguments (http://localhost:55555/lib/angular2-polyfills.js:1401:36)
    at lib$es6$promise$promise$$Promise.obj.(anonymous function) [as then] (http://localhost:55555/lib/angular2-polyfills.js:1413:46)
    at TemplateNormalizer.normalizeTemplate (http://localhost:55555/lib/angular2.js:20007:44)
    at TemplateCompiler.normalizeDirectiveMetadata (http://localhost:55555/lib/angular2.js:24233:39)
    at http://localhost:55555/lib/angular2.js:24306:24
    at Array.map (native)
    at Array.map (http://localhost:55555/lib/es6-shim.js:1113:14)

-----async gap-----
Error
    at _getStacktraceWithUncaughtError (http://localhost:55555/lib/angular2-polyfills.js:2236:29)
    at Zone.fork (http://localhost:55555/lib/angular2-polyfills.js:2285:47)
    at NgZone._createInnerZone (http://localhost:55555/lib/angular2.js:13426:39)
    at new NgZone (http://localhost:55555/lib/angular2.js:13292:32)
    at createNgZone (http://localhost:55555/lib/angular2.js:12475:12)
    at PlatformRef_.application (http://localhost:55555/lib/angular2.js:12550:31)
    at Object.bootstrap (http://localhost:55555/lib/angular2.js:24805:64)
    at execute (http://localhost:55555/app/main.js:28:23)
    at u (http://localhost:55555/lib/system.js:5:3330)
    at Object.execute (http://localhost:55555/lib/system.js:5:6218)BrowserDomAdapter.logError @ angular2.js:23083
:55555/app/main.js:31 BaseExceptionmessage: "Template parse errors:↵Unexpected character "EOF" ("↵   test
↵    
↵</foot[ERROR ->]"): AppComponent@22:6"stack: "Error: Template parse errors:↵Unexpected character "EOF" ("↵   test
↵    
↵</foot[ERROR ->]"): AppComponent@22:6↵    at new BaseException (http://localhost:55555/lib/angular2.js:7351:21)↵    at TemplateNormalizer.normalizeLoadedTemplate (http://localhost:55555/lib/angular2.js:20019:15)↵    at http://localhost:55555/lib/angular2.js:20008:24↵    at Zone.run (http://localhost:55555/lib/angular2-polyfills.js:1243:24)↵    at Zone.run (http://localhost:55555/lib/angular2.js:13438:32)↵    at zoneBoundFn (http://localhost:55555/lib/angular2-polyfills.js:1220:26)↵    at lib$es6$promise$$internal$$tryCatch (http://localhost:55555/lib/angular2-polyfills.js:468:17)↵    at lib$es6$promise$$internal$$invokeCallback (http://localhost:55555/lib/angular2-polyfills.js:480:18)↵    at lib$es6$promise$$internal$$publish (http://localhost:55555/lib/angular2-polyfills.js:451:12)↵    at http://localhost:55555/lib/angular2-polyfills.js:123:10"__proto__: __(anonymous function) @ :55555/app/main.js:31

When I check the AppComponent.ts class

import {Component} from 'angular2/core';
import {RouteConfig, Router, ROUTER_DIRECTIVES} from 'angular2/router';
import {FORM_PROVIDERS} from 'angular2/common';
import {RouterActive} from './router-active';
import {Schoolyears} from './schoolyears/schoolyear.component';
import {Administration} from './administration/administration.component';
import 'rxjs/add/operator/map';

@Component({
    selector: 'my-app',
    providers: [...FORM_PROVIDERS],
    directives: [...ROUTER_DIRECTIVES, RouterActive],
    pipes: [],
    styles: [],
    templateUrl: './app/app.html'   
})
@RouteConfig([
      { path: '/', component: Schoolyears, name: 'Index' },
        { path: '/schoolyears', component: Schoolyears, name: 'Index' },
        { path: '/administration', component: Administration, name: 'Administration' }

       //{ path: '/', redirectTo: ['Index'] } // otherwise url when not exist
])
export class AppComponent {
     name = 'Angular 2 Webpack Starter';
    url = 'https://twitter.com/AngularClass';
    constructor() {

    }
}

or the app.html

<header>
    <nav>
        <h1>Hello {{ name }}</h1>
        <ul>
            <li router-active>
                <a [routerLink]="['Index']">Schoolyears</a>
            </li>
            <li router-active>
                <a [routerLink]="['Administration']">Administration</a>
            </li>

        </ul>
    </nav>
</header>

<main>
    <router-outlet></router-outlet>
</main>

<footer>
   test

</footer>

My main.ts which is the entry poin to everything

///<reference path="../node_modules/angular2/typings/browser.d.ts"/>

import {provide} from 'angular2/core';
import {bootstrap, ELEMENT_PROBE_PROVIDERS} from 'angular2/platform/browser';
import {ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import {HTTP_PROVIDERS} from 'angular2/http';
//import {APP_BASE_HREF} from 'angular2/router';


const ENV_PROVIDERS = [];
ENV_PROVIDERS.push(ELEMENT_PROBE_PROVIDERS);

import {AppComponent} from './app.component'

bootstrap(AppComponent, [
    ...ENV_PROVIDERS,
    ...HTTP_PROVIDERS,
    ...ROUTER_PROVIDERS,
    provide(LocationStrategy, { useClass: HashLocationStrategy })

])
    .catch(err => console.error(err));

I can not see anything wrong.

How can I fix that?

UPDATE

In the main.js file I seem to get this error "if" that is the real error...

enter image description here

4 Answers

This error is tricky, since the error message is often misleading. The error will show one of your last lines of HTML; however, don't search for the issue there! This is simply the case because a tag was not closed properly beforehand.

This error is fixed by closing a tag which is missing its closing tag. Sometimes, like in my case of <textarea>, this is tricky to catch because Angular is satisfied if <input> is unclosed; however, <textarea> must be closed.

If you're wondering which HTML element tags must be closed, simply search for tag omission in regards to the specific element you're curious about.

Consider running your HTML through a linter in order to quickly catch these errors!


Code example of my situation

In my case, I was not closing one of my <textarea> elements.

Previously my code was as follows

<div class="form-group col-sm-6">
  <label for="example" class="form-label">Example</label>
  <textarea class="form-control" name="example" formControlName="example" lines="2">
</div>

To fix this issue, I simply closed the <textarea> element, as follows

<div class="form-group col-sm-6">
  <label for="example" class="form-label">Example</label>
  <textarea class="form-control" name="example" formControlName="example" lines="2"></textarea>
</div>
Related