Rendering HTML - ldco2016/microurb_web_framework GitHub Wiki

export class UserForm {
  constructor(public parent: Element) {}

  template(): string {
    return `<div>
      <h1>User Form</h1>
      <input />
    </div>`;
  }

  render(): void {
    const templateElement = document.createElement("template");
    templateElement.innerHTML = this.template();

    this.parent.append(templateElement.content);
  }
}

I can test this out inside of my index.ts file:

import { UserForm } from "./views/UserForm";

const userForm = new UserForm();

Now I can create an instance to a UserForm and when I do so I have to pass in a reference to an HTML element and that element is where we place all the content for UserForm. So I will open up my index.html file and add in some div that will serve as the absolute parent element of my entire application like so:

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
    <script src="./src/index.ts"></script>
  </body>
</html>

I will go back to index.ts and into the constructor pass a document.getElementById() like so:

import { UserForm } from "./views/UserForm";

const userForm = new UserForm(document.getElementById("#root"));

That will create an instance of UserForm and to actually get some HTML to show up I do a userForm.render() like so:

import { UserForm } from "./views/UserForm";

const userForm = new UserForm(document.getElementById("#root"));

userForm.render();

To ensure that Parcel sees the update to the HTML file, I will go back over to the terminal and restart with parcel index.html. Do not forget you also need to have another panel in your terminal running: json-server -w db.json.

Now I can take a look back in the browser, but unfortunately all I saw was a blank screen and an error in the console saying Uncaught TypeError: Cannot read property 'append' of null.

I got that error because in the world of TypeScript, when using the Element property which is the most base class from which all objects in the DOM inherit, can also come up null.

So it appears that the key to solving this is the not-null assertion operator or what in the world of English grammar we know as the exclamation point and I think in the world of Ruby they call the she-bang.

Basically, you tell TypeScript to relax and stop yelling at you because you know what you are doing. The root constant will definitely reference Element. Otherwise, if the operator were to be omitted, root could refer to Element or null, if the element could not be found.

So the solution looks like this:

import { UserForm } from "./views/UserForm";

const root: Element = document.getElementById("root")!;

const userForm = new UserForm(root);

userForm.render();

Once that solution was implemented I was able to see the form on the screen in the browser.

⚠️ **GitHub.com Fallback** ⚠️