0

(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")
    ]
}

}

adiga
  • 34,372
  • 9
  • 61
  • 83
Zeeshan Malik
  • 627
  • 1
  • 14
  • 31

1 Answers1

1

you are trying to use undefined variable.

you have declared those parameters:

inputTitle: HTMLInputElement;
inputLink: HTMLInputElement;
td: HTMLTableCellElement;
tdTitle: HTMLTableCellElement;
tdLink: HTMLTableCellElement;
tr: HTMLTableRowElement;
tBody: HTMLElement = document.getElementsByTagName("tbody")[0];

you need also to declare your 'div'.

this.div.appendChild(this.inputTitle);

but note you do not have any 'div' defined.

Yalin
  • 345
  • 2
  • 9