3

Im currently trying to get into Typescript for an upcoming school project, but im having a problem with testing my little program. What i want to achieve is that when I click a button, my program starts running. The thing is that i cant manage to get the function in my GameManager class to execute when i click the button. The 3 relevant files that i use are:

index.html, in which I setup the button

GameManager.ts, which contains the function that i want to call

Test.ts, which is the file in which I want to test my program


GameManager.ts

This file contains the function updateCycle() that I want to call

import { Inventory } from "./Inventory"
import { ForeignTrader } from "./ForeignTrader";

export class GameManager {

    private timer;
    inventory: Inventory;
    foreignTrader: ForeignTrader;

    constructor() {

    }

    public gameLoop() {
        this.inventory.update(this.foreignTrader.getResourceDelivery());
    }    
    public updateCycle() {
        setInterval(() => this.gameLoop(), 5000);
    }
} 

index.html

<html>
<head>
    <link rel="stylesheet" type="text/css" href="interface.css" />
</head>
<body>
    <button id="button1" onclick="updateCycle()">Click Me!</button>
    <br />
    Gold: <span id="gold">0</span>
    <br />
    Wood: <span id="wood">0</span>
    <br />
    <script type="text/javascript" src="Library.js"></script>
    <script type="text/javascript" src="Resources.js"></script>
    <script type="text/javascript" src="Inventory.js"></script>
    <script type="text/javascript" src="ForeignTrader.js"></script>
    <script type="text/javascript" src="GameManager.js"></script>
    <script type="text/javascript" src="Test.js"></script>

</body>
</html>

I already tried googling and what seems to be the problem is my function being in a local scope as I always get the error:

(index):6 Uncaught ReferenceError: updateCycle is not defined
at HTMLButtonElement.onclick (http://localhost/TradeGame/Trade%20Game/:6:48)
onclick @ (index):6

But no matter what I try, I just have no clue how to get my needed function into the global scope. The main problem here is, that I also cant import the GameManager into my Test.ts file as this will automatically give it its own scope. Is there any way that lets me use the function when i click on the button?

the tsconfig.json looks like this:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "sourceMap": false
    },
    "exclude": [
        "node_modules"
    ]
}
3
  • 1
    By the syntax you are using I'm guessing you are generating modules, it will be a bit more complicated to reference the code in html. You will need a module loader to load it first. Could you share your tsconfig.json file too? Commented Dec 11, 2016 at 0:55
  • I edited the post and included the surce code for the tsonfig at the bottom of my post. I didn't use internal modules, just classes that i export and then import into other files. To my understanding right now every class that i create gets automatically included in the external module commonjs, right? The imports at the top of my GameManager file are just a class in a separate file. Commented Dec 11, 2016 at 17:09
  • 1
    you are using commonjs modules. :) Commented Dec 11, 2016 at 18:58

1 Answer 1

2

Unfortunately, since browsers don't natively support commonjs modules, this will be tough but not impossible without a bundler.

Before you read any further, take a look at Webpack, Browserify, or SystemJS. Typescript also has a webpack tutorial on their website (it is using react, but I think you can still get the idea).

If a bundler is beyond the scope of your project, or you just really want to proceed as normal you can't import/export things from separate files.

If you try loading in your scripts as you have them, you are probably also seeing errors like this in your console, right?:

Uncaught ReferenceError: require is not defined

That's what a bundler fixes.It injects the script you are importing/exporting in place of all of those requires.

To fix this without using a bundler everything will have to live in the same file (yuck). But - just for the sake of being thorough - I have an example below of GameManager being called on button click.

index.html

tml>
<head>
</head>
<body>
    <button id="button1" onclick="manager.updateCycle()">Click Me!</button>
    <br />
    Gold: <span id="gold">0</span>
    <br />
    Wood: <span id="wood">0</span>
    <br />
    <script type="text/javascript" src="test.js"></script>
    <script>
        var manager = new GameManager();
    </script>
</body>
</html>

test.ts

class GameManager {
    updateCycle(): void {
        console.log('Update')
    }   
}

A few final notes:

  • Notice that I removed the export from your original example. That would create another syntax error in the browser.
  • I also new-ed up an instance of GameManager after the import because updateCycle is a public function (and not a static one). I also updated the onClick in the button to reflect this.
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, this was great help. I implemented Browerify and everthings working great now!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.