4

I have this module.ts file:

import { IHttpService, IPromise } from 'angular';

export class ProductService {
    static $inject = ["$http"];
    constructor(private $http: IHttpService) { }

    loaded: boolean = false;
    promise: IPromise<{ data: any }>;

    getProducts(): IPromise<{ data: any }> {
        if (!this.loaded) {
            this.loaded = true;
            this.promise = this.$http.get('/products.json');
        }
        return this.promise;
    }
}

var module = angular.module("psShopping", ["ngComponentRouter"]);
module.value("$routerRootComponent", "shoppingApp");
module.service('products', ProductService);

and this gets transpiled/compiled to module.js:

"use strict";
var ProductService = (function () {
    function ProductService($http) {
        this.$http = $http;
        this.loaded = false;
    }
    ProductService.prototype.getProducts = function () {
        if (!this.loaded) {
            this.loaded = true;
            this.promise = this.$http.get('/products.json');
        }
        return this.promise;
    };
    ProductService.$inject = ["$http"];
    return ProductService;
}());
exports.ProductService = ProductService;
var module = angular.module("psShopping", ["ngComponentRouter"]);
module.value("$routerRootComponent", "shoppingApp");
module.service('products', ProductService);

The problematic line is: exports.ProductService = ProductService; If I remove this manually - the app works perfectly. But if I leave this like that, in the browsers console I get an error "exports is not defined". What can be done about this? I can't just remove "export" from the .ts file as this class is used in other files (I import it there). I tried different compiler options, but it just gives me different errors (like "define is not defined" etc) and I'm not sure how to handle this. maybe theres a way that the tsc would just not produce this line?

Dale K
  • 25,246
  • 15
  • 42
  • 71
marc08
  • 411
  • 6
  • 15
  • 1
    How are you loading modules in the browser? Are you using browserify/webpack/jspn etc??? Do you need to export the class? – Daniel Tabuenca Nov 16 '16 at 02:04
  • i just have an index.html with attaching all the scripts files. One of the files that i attach is the one above (module.js). I only have one module in the app (called psShopping). – marc08 Nov 16 '16 at 02:08
  • set `"module" :"none"` option in your tsconfig – Daniel Tabuenca Nov 16 '16 at 02:13
  • You will only be able to get so far though without using a module loader in the browser. You will be restricted to importing just types, not other modules. – Daniel Tabuenca Nov 16 '16 at 02:13
  • I see, yeah now i get "Cannot use imports, exports, or module augmentations when '--module' is 'none'." So how do i modify module.ts file now to make it all work? Or what are the other ways i can make this work (using module loader in the browser?) – marc08 Nov 16 '16 at 02:19
  • don't use imports/exports you need to use `///` statemnents to load type definitions from angular – Daniel Tabuenca Nov 16 '16 at 02:23
  • The types should be available in the `ng` namespace so you use `ng.IHttpService` etc.. wihtout doing imports – Daniel Tabuenca Nov 16 '16 at 02:24
  • oh yes! it works! Thank you so much! I spent so many hours trying to figure this out... Thanks a lot man!! How can i learn more about this? I feel so mixed up between angular 1.5 and 2.0 and different version of typescripts.. and i just started learning a couple weeks ago.. – marc08 Nov 16 '16 at 02:33
  • Modules, module resolution and loading declarations are probably the most difficult and confusing parts of learning typescript. I'm planning on making some blog posts around this area to further explain. This post might help explain some of these things: http://stackoverflow.com/questions/40222162/typescript-2-custom-typings-for-untyped-npm-module/40326719#40326719 – Daniel Tabuenca Nov 16 '16 at 02:39
  • Great! Thank you! I really appreciate your help! – marc08 Nov 16 '16 at 02:49

1 Answers1

3

Whenever you use the import and export keywords in typescript, you are converting the file to act as a module.

Modules are designed to work along with module systems like commonjs,amd, es6, systemjs etc...

If your are trying to load a raw script in a browser without using a module-loader or bundler such as systemjs, webpack, browserify, jspm, etc... then you cannot use external modules (so you can't use import/exports).

You can still use typings from definitely typed, but you have to load them through ///<reference /> tags.

If using typescript 2.0 typings like angular are also available and imported by default when you run

npm install @types/angular

Usually these typings will expose global namespace declaration that you will now be able to use throughout your application.

For example in your case angular exposes an ng namespace and you would use it like:

  promise: ng.IPromise<{ data: any }>;

You can also easily alias it:

import IPromise = ng.IPromise

Note that this import behaves differently than module imports (it just aliases).

If you are going to do anything other than a trivial application, I would strongly recommend you use a module loader such as webpack to compile and bundle the application for the browser. There are many limitations to just using plain scripts.

Dale K
  • 25,246
  • 15
  • 42
  • 71
Daniel Tabuenca
  • 13,147
  • 3
  • 35
  • 38