(click) event in typescript causes error given below.
EXCEPTION: Error during evaluation of "click"
ORIGINAL EXCEPTION: TypeError: Cannot read property 'appendChild' of undefined
angular2.dev.js:23877 ORIGINAL STACKTRACE:
angular2.dev.js:23877 TypeError: Cannot read property 'appendChild' of undefined
at Playlist.addVideo (playlist.component.ts:53)
at ChangeDetector_Playlist_0.handleEventInternal (viewFactory_Playlist:62)
at ChangeDetector_Playlist_0.AbstractChangeDetector.handleEvent (angular2.dev.js:9568)
at AppView.triggerEventHandlers (angular2.dev.js:10246)
at eval (viewFactory_Playlist:361)
at angular2.dev.js:14068
at angular2.dev.js:13496
at ZoneDelegate.invoke (angular2-polyfills.js:332)
at Object.onInvoke (angular2.dev.js:2111)
at ZoneDelegate.invoke (angular2-polyfills.js:331)
ERROR CONTEXT:
BrowserDomAdapter.logError @ angular2.dev.js:23877
ExceptionHandler.call @ angular2.dev.js:1333
(anonymous) @ angular2.dev.js:12763
schedulerFn @ angular2.dev.js:13167
SafeSubscriber.__tryOrUnsub @ Rx.js:10775
SafeSubscriber.next @ Rx.js:10730
Subscriber._next @ Rx.js:10690
Subscriber.next @ Rx.js:10667
Subject._finalNext @ Rx.js:11191
Subject._next @ Rx.js:11183
Subject.next @ Rx.js:11142
EventEmitter.emit @ angular2.dev.js:13148
onError @ angular2.dev.js:13566
onHandleError @ angular2.dev.js:2128
ZoneDelegate.handleError @ angular2-polyfills.js:336
Zone.runGuarded @ angular2-polyfills.js:244
NgZoneImpl.runInner @ angular2.dev.js:2140
NgZone.run @ angular2.dev.js:13649
outsideHandler @ angular2.dev.js:13495
ZoneDelegate.invokeTask @ angular2-polyfills.js:365
Zone.runTask @ angular2-polyfills.js:263
ZoneTask.invoke @ angular2-polyfills.js:431
angular2.dev.js:23877 EventEvaluationErrorContext {element: button.btn.btn-success, componentElement: playlist, context: Playlist, locals: Object, injector: Injector}
I want that when I click on add Video button a dynamically generated new editable row will append to table, whose value I want to pass to another class.
inputTitle: HTMLInputElement;
inputLink: HTMLInputElement;
td: HTMLTableCellElement;
tdTitle: HTMLTableCellElement;
tdLink: HTMLTableCellElement;
tr: HTMLTableRowElement;
tBody: HTMLElement = document.getElementsByTagName("tbody")[0];
addVideo()
{
this.inputTitle = document.createElement("input");
this.inputLink = document.createElement("input");
this.td = document.createElement("td");
this.tdTitle = document.createElement("td");
this.tdLink = document.createElement("td");
this.tr = document.createElement("tr");
this.inputTitle.setAttribute("type", "text");
this.div.appendChild(this.inputTitle);
this.inputLink.setAttribute("type", "text");
this.tdTitle.appendChild(this.inputTitle);
this.tdLink.appendChild(this.inputLink);
this.tr.appendChild(this.td);
this.tr.appendChild(this.tdTitle);
this.tr.appendChild(this.tdLink);
this.tBody.appendChild(this.tr);
}
And also the above method works fine. But this addVideo() cause problem.
Click here to see what I want. If anyone got other suggestion kindly tell me. Thanks.
Here's playlist.component.ts file
import {Component, Input} from "angular2/core";
import {Video} from "./video";
@Component(
{
selector: "playlist",
templateUrl: "app/ts/playlist.component.html",
inputs: ["videos"]
})
export class Playlist
{
iframe: HTMLIFrameElement;
div: HTMLDivElement = document.getElementsByTagName("div")[0];
inputTitle: HTMLInputElement;
inputLink: HTMLInputElement;
td: HTMLTableCellElement;
tdTitle: HTMLTableCellElement;
tdLink: HTMLTableCellElement;
tr: HTMLTableRowElement;
tBody: HTMLElement = document.getElementsByTagName("tbody")[0];
onSelect(vid: Video)
{
if(this.iframe)
this.div.removeChild(this.iframe);
this.iframe = document.createElement("iframe");
this.iframe.setAttribute("width", "800");
this.iframe.setAttribute("height", "500");
this.iframe.setAttribute("src", "https://www.youtube.com/embed/" + vid.link);
this.div.appendChild(this.iframe);
}
addVideo()
{
this.inputTitle = document.createElement("input");
this.inputLink = document.createElement("input");
this.td = document.createElement("td");
this.tdTitle = document.createElement("td");
this.tdLink = document.createElement("td");
this.tr = document.createElement("tr");
this.inputTitle.setAttribute("type", "text");
this.div.appendChild(this.inputTitle);
this.inputLink.setAttribute("type", "text");
this.tdTitle.appendChild(this.inputTitle);
this.tdLink.appendChild(this.inputLink);
this.tr.appendChild(this.td);
this.tr.appendChild(this.tdTitle);
this.tr.appendChild(this.tdLink);
this.tBody.appendChild(this.tr);
}
}
Here's playlist.component.html file
<div>
<div style = "position: relative;" class = "btn-group">
<button class = "btn btn-success" (click) = "addVideo()">Add Video</button>
<button class = "btn">Edit <span class = "glyphicon glyphicon-pencil"></span></button>
</div>
<div class = "table-responsive">
<table class = "table table-striped table-hover" border = "0">
<thead>
<tr style ="font-weight: bold">
<td>ID</td>
<td>Title</td>
<td>Video Code</td>
</tr>
</thead>
<tbody id = "VideoEntries">
<tr *ngFor = "#v of videos" (click) = "onSelect(v)">
<td>{{v.id}}</td>
<td>{{v.title}}</td>
<td>{{v.link}}</td>
</tr>
</tbody>
</table>
</div>
Here's app.component.ts file
import {Component} from "angular2/core";
import {Video} from "./video";
import {Config} from "./config.service";
import {Playlist} from "./playlist.component";
@Component(
{
selector: "my-app",
templateUrl: "app/ts/app.component.html",
directives: [Playlist]
})
export class AppComponent
{
Heading = Config.HEADING;
videos: Array<Video>;
constructor()
{
this.videos =
[
new Video(1, "Angular1", "hXfigUyeHaY"),
new Video(2, "Angular2", "MyqcsnbH820")
]
}
}