Pqformelpro
Pqformelpro

Reputation: 33

Typescript: Using class functions in the global scope

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

Upvotes: 3

Views: 1199

Answers (1)

drewwyatt
drewwyatt

Reputation: 6027

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.

Upvotes: 2

Related Questions