1

I have a class in one file and I'm trying to create new objects from it that are loaded up in my E2E $httpBackend, but the browser can't seem to figure it out. The whole application doesn't load and this error appears in the console:

Uncaught TypeError: app.Challenge is not a function

The TyepScript compiler (I'm using WebStorm to auto-compile.) has no complaints and it compiles fine. The module with the class is like so:

module app {
  "use strict";

    // interfaces here

    export class Challenge implements IChallenge {

        constructor(public answerString: string,
                    public difficulty: number,
                    public id: string,
                    public language: languages,
                    public name: string,
                    public tests: ITest[]) {
        }
    }
}

And my mockBackend for my angular app is this:

module app.development {
    "use strict";

    angular
        .module("appMock", ["ngMockE2E"])
        .run(challengeResourceMock);

    challengeResourceMock.$inject = ["$httpBackend"];
    function challengeResourceMock($httpBackend: ng.IHttpBackendService): void {
        var challenges: app.IChallenge[] = [];
        var challenge: app.IChallenge;


        challenge = new app.Challenge( // <-- It says this is not a function!
            "runThisFunction = function(str) {\n\treturn str.split('').reverse().join('');\n}",
            1, "1", 1, "Reverse a String", [{
                description: "make sure it reverses the string (e.g. 'start' will become 'trats)",
                test: "function () {\n\tvar a = 'abcdef';\n\texpect(runThisFunction(a)).toEqual('fedcba');\n}"
            }]);
        challenges.push(challenge);

        // ...more challenges added to the list

        // get all challenges
        $httpBackend.whenGET("api/challenge").respond(200, challenges);

        // pass through requests for anything else
        $httpBackend.whenGET(/./).passThrough();
    }

}

How do I clear the error and get my app working with the mock backend?

UPDATE:

I've now removed the TypeScript modules. On basarat's advice I'm only using commonjs modules. I'm now using the ts-loader with webpack instead of WebStorm's compiler. I added a tsconfig file:

{
    "compilerOptions": {
      "target": "ES5",
      "module": "commonjs",
      "noImplicitAny": true,
      "outDir": "./dist/tsOutput/",
      "preserveConstEnums": true,
      "removeComments": true,
      "sourceMap": true
    },
  "exclude": ["node_modules", "trash", "coverage"]
}

Currently everything is in the global space, which isn't ideal but the application isn't big enough yet for there to be any conflicts. I'm, now, getting a slightly different error message, but the effect is the same. The application won't run.

Uncaught ReferenceError: Challenge is not defined

"Build" doesn't seem to be working. My IDE's inspector has no complaints. It's as if "class" isn't doing anything at all.

TEMPORARY HACK

Well, after fiddling for quite a while, I decided I was running out of time and decided to replace my Challenge objects with object literals.

module app {
    "use strict";

    angular
        .module("appMock", ["ngMockE2E"])
        .run(challengeResourceMock);

    challengeResourceMock.$inject = ["$httpBackend"];
    function challengeResourceMock($httpBackend: ng.IHttpBackendService): void {
        var challenges: app.IChallenge[] = [];
        var challenge: app.IChallenge;

        challenge = {
            answerString: "runThisFunction = function(str) {\n\treturn str.split('').reverse().join('');\n}",
            difficulty: 1,
            id: "1",
            language: 1,
            name: "Reverse a String",
            tests: [{
                description: "make sure it reverses the string (e.g. 'start' will become 'trats)",
                test: "function () {\n\tvar a = 'abcdef';\n\texpect(runThisFunction(a)).toEqual('fedcba');\n}"
            }]
        };
        challenges.push(challenge);

        // additional obj literal challenges    

        // get all challenges
        $httpBackend.whenGET("api/challenge").respond(200, challenges);

        // pass through requests for anything else
        $httpBackend.whenGET(/./).passThrough();
    }

}

Obviously, I must return to this issue in the future, but I'm further in my project for now.

2
  • Since you are now using commonjs (which is a good thing), did you import {Challenge} from ' ./Challenge.ts' in your second file ? Commented Feb 9, 2016 at 16:49
  • Darn. I wanted that to be the solution. :D The compiler is now giving error "TS2307: Cannot find module './challenge.ts'". I have been using "require's". Everything in my application should be concatenated and in the same name space. I see the challenge.ts file in the list of file bundled by webpack. Commented Feb 9, 2016 at 17:00

1 Answer 1

1

Uncaught TypeError: app.Challenge is not a function

A common issue with using --out. Please use external modules (prefer --module commonjs).

Docs

https://github.com/TypeStrong/atom-typescript/blob/master/docs/out.md

More

Another answer: typescript output order - gulp equivalent to tsc with tsconfig.json

Sign up to request clarification or add additional context in comments.

3 Comments

So, are you saying forget the "module's"? I thought they were needed for good namespaceing?
I'm using WebStorm. I've been letting it automatically compile the ts for me. Will I have to switch to some build tool?
Here is some info straight out of jetbrains blog : blog.jetbrains.com/webstorm/2015/09/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.