How to remove list item from Typescript todo list app

I am attempting to build a basic todo list app using ONLY Typescript, HTML, and CSS. app.ts is set up to listen for a submit event. The ListTemplate class defines a render method used to create and append the list item elements to the DOM. The ListItem class defines listItem as a string type and executes the format() function defined in the HasFormatter interface. List items are dynamically appended to <ul></ul> container in the HTML. The functionality to input text and append list items to the DOM currently works fine. I am now trying to append functioning remove item buttons to each list item, which I set up in the render method: const btn = document.createElement('button'). I am not sure how to set up the functionality to remove individual list items when clicking the remove buttons. I tried adding another event listener to app.ts that listens for the remove button with the id listItemBtn, but am not sure how to set up the listener (or potentially a remove method in ListTemplate) to target specific list items when clicking remove button. Any thoughts on how to do this? Thanks!

Here is the CodeSandBox link for the project:


import { ListItem } from './classes/ListItem.js';
import { ListTemplate } from './classes/ListTemplate.js';
import { HasFormatter } from './interfaces/HasFormatter.js'

const form = document.querySelector('#newForm') as HTMLFormElement; // typecasting, casting the element to be a certain type
const listItemBtn = document.querySelector('#listItemBtn') as HTMLButtonElement;
const listItem = document.querySelector('#listItem') as HTMLInputElement;

//list template instance
const ul = document.querySelector('ul')!;
const list = new ListTemplate(ul)

form.addEventListener('submit', (e: Event) => {

    let values: [string] // tuple
    values = [listItem.value]

    let doc: HasFormatter;

    doc = new ListItem(...values)

    list.render(doc, listItem.value, 'start')

listItemBtn.addEventListener('onclick', (e: Event) => {


import { HasFormatter } from "../interfaces/HasFormatter.js";

export class ListTemplate {
    constructor(private container: HTMLUListElement){}

    render(item: HasFormatter, heading: string, position: 'start' | 'end'){
        const li = document.createElement('li');

        const p = document.createElement('p');
        const btn = document.createElement('button');
        btn.setAttribute('id', 'listItemBtn')
        p.innerText = item.format();

        if (position === 'start'){
        } else {

    remove() {


import { HasFormatter } from '../interfaces/HasFormatter.js'

export class ListItem implements HasFormatter { //ensuring that all structures follow HasFormatter structure
        public listItem: string
    ) {}

    format() {
        return `${this.listItem}`


export interface HasFormatter {
    format(): string


<html lang="en">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>TypeScript Tutorial</title>
  <!-- <link rel="stylesheet" href="styles.css"> -->

    <form id="newForm">
      <div class="field">
        <label>List item</label>
        <input type="text" id="listItem">

    <div class="wrapper">

      <!-- output list -->
      <ul class="item-list">

  <script type="module" src='app.js'></script>

1 answer

  • answered 2021-04-08 06:34 Eliseo

    I'm not prety sure but I think that shoul be some like

    listItemBtn.addEventListener('onclick', (e: Event) => {
        //get the "<li>" where the button is
        //remove it