1

I know that this exception:

Unexpected directive value 'undefined' on the View of component 'AppComponent'

is quite common, but no other question helped me, since they often refer to circular dependencies or missing export statements. But no fix fits to this problem...

I have a project with the following structure

src/
    myproject/
        components/
        services/
        templates/
        ...
        main.ts
    index.html
    systemjs.config.js
public/
    libs/                   <- required libs, copied from node_modules
    myproject/              <- compiled .ts files and copied resources from /src/myproject
    index.html              <- copied from /src/myproject
    systemjs.config.js      <- copied from /src/myproject
gulpfile.ts
*.json                      <- tsconfig, package, typings, ...

The process to deploy the project is the following: compile .ts files, output them to /public. Copy all resources (everything but .ts files) to /public. Copy all required libs to /public/libs.

I am using typescript 1.9, since I am using the paths option in tsconfig.json. This file contains the following path mapping:

// excerpt from /tsconfig.json
{
    "compilerOptions": {
        // more options
        "paths": {
            "myproject/*": ["./src/myproject/*"]
        }
        // more options
    }
}

All my Angular2 components are in the folder /src/myproject/components and there is an index.ts file which exports every defined class. This file looks like this:

// /src/myproject/components/index.ts
export * from './app.component';
export * from './a.component';
export * from './b.component';
export * from './c.component';

The reason for this setup is to be able to have good looking and easy imports. For example, if I need ComponentA, ComponentB and ComponentC (which are defined in /src/myproject/components/{a,b,c}.component.ts), then I can just make the following statement:

// excerpt from /src/myproject/components/app.component.ts
import  { ComponentA, ComponentB, ComponentC } from 'myproject/components';

This does work very well: I have no issues when compiling, and no issues when accessing it in the browser (systemjs.config.js takes care of the proper resolution)

But there is one exception. If I import the main AppComponent (/src/myproject/components/app.component.ts) in the main.ts file (/src/myproject/main.ts) like this:

// excerpt from /src/myproject/main.ts
import { AppComponent } from 'myproject/components';

I get the following exception when trying to view myproject in the browser:

EXCEPTION: Unexpected directive value 'undefined' on the View of component 'AppComponent'

However, if I change this import to the following:

// excerpt from /src/myproject/main.ts
import { AppComponent } from 'myproject/components/app.component';

Everything works as expected. Please note, that the main.ts is the only file where this import does not work. All other imports work like a charm. For example, in AppComponent, like you can see above.

If I would write everything down, this question would be way to large, so please excuse me that I decided to only add a MWE as a GitHub repository. You can get the whole code from:

https://github.com/christiandreher/ang-exc-mwe

I also pushed the /public directory. Accessing this with a browser, you should technically get the same error. If you want to build it yourself, you can use gulp clean, tsc (note: gulp build does not work due to a bug in gulp-typescript), gulp resources, gulp libs.

So the question is: Why does every import work, except for the first one in main.ts? I really like this setup, since I can import everything very conveniently and it just looks good. Also, I want it consistently.

I really appreciate any help, since this is a huge question, and to be honest, a not so minimal working example...

Update: So far I have only received answers on how to fix the exception, but I have supplied a fix for this by myself in the OP. I know how to avoid it, but I don't want to use relative imports, I want it constistently everywhere. So what can I do to fix this one exception? What is the cause of this? If it is not fixable: Why? Who do I have to address for this issue? TypeScript, Angular, ...?

Update 2: As I still didn't manage to get this to work, I will now start a bounty

CharlyDelta
  • 938
  • 11
  • 31

3 Answers3

2

Put export * from './app.component'; at the end of the index.ts

// /src/myproject/components/index.ts
export * from './a.component';
export * from './b.component';
export * from './c.component';
export * from './app.component';

I suppose it should work, since I had the same problem.


If it doesn't, do the below:

  • Think of index.ts as having all the code of exported files written in it.

  • And then reorder the exports according to define first use later rule

  • Don't use index.ts as proxy for the files that are exported in it, and uses some other file that is also exported from the same index.ts file, and vice-versa (aka: circular-dependency). In other words

  • Wherever you can do ./some-component to import, don't use index.ts there, which is necessary if you have some-other-component in the same index.ts (read Directory) importing each other from index.ts, this will fail.

  • Same above applies to services as well.

  • It should work by now, if doesn't, look at constructor of AppComponent and see if there are other index.ts exports in use, having internal dependencies with each other, then reorder them with same rule.

  • This is the same reason why we don't define two classes in a single file.

Ankit Singh
  • 24,525
  • 11
  • 66
  • 89
  • Indeed putting the `app.component` at the bottom of the `index.ts` file solved the problem! I am so happy, thank you very much :) So it actually _was_ a circular dependency problem, right? – CharlyDelta May 22 '16 at 10:13
  • You're welcome.... me too, for obvious reasons ;) ..... hm, not actually, more of `used before declaration`, I think. – Ankit Singh May 22 '16 at 10:30
  • 1
    Hmm interessting... I think there is a lot of improvement potential regarding typescript. This shouldn't be an issue imho – CharlyDelta May 22 '16 at 11:46
0

I would import like this:

// excerpt from /src/myproject/main.ts
import { AppComponent } from './components';

with the following SystemJS configuration:

System.config({
  (...)
  packages: {
    (...)
    src: {
      main: 'index.js',
      defaultExtension: 'js'
    }
  }
});
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • The question is: why does it not work with `myproject/components`? There must be an error somewhere, because in all other files it does work. I would like to have it consistently – CharlyDelta May 17 '16 at 12:16
0

update

For me only relative paths work with me, when I import an absolute path not working correctly except those in node_modules I found an useful link can help you Angular2 & TypeScript importing of node_modules.


You need to change the import to

import { AppComponent } from './components';

It works fine for me

Community
  • 1
  • 1
Muhammad Hassan
  • 475
  • 2
  • 14
  • This doesn't answer my question, too. I would like to leave it as it is, with `myproject/components`, and fix the error why this one, single import is not working – CharlyDelta May 17 '16 at 12:17
  • For me only relative paths work with me, when I import an absolute path not working correctly except those in `node_modules` I found an useful link can help you [Angular2 & TypeScript importing of node_modules](http://stackoverflow.com/questions/35159872/angular2-typescript-importing-of-node-modules) – Muhammad Hassan May 17 '16 at 14:10
  • The repo referenced in the OP works with absolute paths. Well, except this single import in `main.ts`. Well, thanks for your effort :) – CharlyDelta May 17 '16 at 14:33