We are going to update the top of app.ts to look like this.

app.ts

import Renderer from './services/renderer';
import ToDo from './models/todo';
import * as wasm from './bincode_parser';
import Network from './services/network';
let app;
wasm.booted.then(() => {
    app = new App();
});

We want to make sure that we wait until the module is booted by waiting for the wasm.booted Promise to resolve. Once we know that everything is ready, we can instantiate our application.

Now our App's constructor needs to pass wasm to the Network constructor.

class App {
    private todos: ToDo[] = [];
    private http: Network
    constructor() {
        this.http = new Network(wasm);
        this.registerEvents();
        this.http.getToDoList()
            .then(todos => {
                this.todos = todos
                this.render()
            })
            .catch(e => {
                Renderer.showMessage('Unable to get todos', true);
            });
    }

Now our app has an http property that will be assigned an instance of our Network class. We can then use that to populate todos using the getToDoList function. Since this returns a promise, we call .then and assign the result to App.todos and render our application for the first time.

Next we need to modify our add, update, and remove functions to no longer use mocks, instead they will use App.http and employ the same pattern as above. That is going to look something like this.

newToDo(ev: MouseEvent) {
    let input = document.getElementById('new-todo') as HTMLInputElement;
    if (!input) return Renderer.showMessage('Unable to find new todo input', true);
    let action = input.value;
    if (action == '') return Renderer.showMessage('New items must have an action', true);
    input.value = '';
    //changes start here
    this.http.addToDoItem(action)
        .then(todos => {
            this.todos = todos;
            Renderer.showMessage('Successfully added new item');
            this.render()
        })
        .catch(e => Renderer.showMessage('Unable to save new item', true));
}

removeToDo(id: number) {
    let match = this.todos.find(t => t.id == id);
    if (!match) return Renderer.showMessage(`Unable to find a todo with the id ${id}`, true);
    //changes start here
    this.http.removeToDoItem(match)
        .then(todos => {
            this.todos = todos;
            Renderer.showMessage('Successfully removed item');
            this.render();
        })
        .catch(e => Renderer.showMessage('Unable to remove item', true));
}

markToDo(id: number, newState: boolean) {
    let match = this.todos.find(t => t.id == id)
    if (!match) return Renderer.showMessage(`Unable to find todo with the id ${id}`, true);
    match.complete = newState;
    //changes start here
    this.http.updateToDoItem(match)
        .then(todos => {
            this.todos = todos;
            Renderer.showMessage('Successfully updated item');
            this.render();
        })
        .catch(e => Renderer.showMessage('Unable to update item', true));
}