Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2.1.2/2.2.0 dependency injection instance undefined

During moving my code from RC4 to 2.1.2, I encountered a strange problem: all my constructor parameters get their value undefined.

I have tried to move providers around from component to app.module.ts to app.component.ts. None of them works.

What's new in 2.1.2 that could make the dependency injector inject "undefined" instead of creating/providing a service instance?

Notes

  1. To make things simpler I changed my code to the following
  2. There is no error message.
  3. If I don't add @Injectable() to AppComponent I would get Can't resovle all parameters for AppComponent (?,?,?)
  4. Please note that the root injector failed to create both the user service and Router instance to feed the AppComponent constructor.
  5. AuthService used to inject Http but I removed it along with other code so that there are less variables to the puzzle.
  6. Tried in Angular 2.2.0 it does not work either.

Any further input?

app.component.ts

import { Component,Injectable }       from '@angular/core'; 
import { Router  } from '@angular/router'; 
import { AuthService }  from '../login/auth.service';

@Component({
  selector: 'my-app',
  template: `
    <h1 class="title">Angular Router</h1>
    <nav>
    </nav>
    <router-outlet></router-outlet>
  `
})
@Injectable()
export class AppComponent {
  constructor(                            // debug here
              private auth: AuthService,  // auth = undefined
              private router: Router,     // router = undefined
              ) {
                console.log("AppComponent constructor");
              }  
}

app.module.ts

import { NgModule }       from '@angular/core';
import { BrowserModule }  from '@angular/platform-browser';
import { FormsModule }    from '@angular/forms';
import { RouterModule }   from '@angular/router';

import { AppComponent }         from './app.component';
import { AuthService }  from '../login/auth.service';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    RouterModule.forRoot([
      { path: '', component: AppComponent },
    ])
  ],
  declarations: [ AppComponent ],
  exports: [RouterModule],
  providers:[AuthService ],
  bootstrap: [ AppComponent ]
})
export class AppModule {}

auth.service.ts

import {Injectable} from '@angular/core';

@Injectable()
export class AuthService {  // the debugger can get to this line but never hit constructor
  private _baseUrl: string;
  loggedIn: boolean = false;
  redirectUrl: string;

  constructor() {
    console.log("AuthService constuctor");
    this.loggedIn = !!sessionStorage.getItem('auth_token');
  }

}

main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './appShell/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

systemjs.config.js

(function(global) {

  var ngVer = '@2.1.2'; // lock in the angular package version; do not let it float to current!
  var routerVer = '@3.1.2'; // lock router version

  //map tells the System loader where to look for things
  var  map = {
    'app':                        'app',

    // angular bundles
    '@angular/core': 'https://npmcdn.com/@angular/core' + ngVer,
    '@angular/common': 'https://npmcdn.com/@angular/common' + ngVer,
    '@angular/compiler': 'https://npmcdn.com/@angular/compiler' + ngVer,
    '@angular/platform-browser': 'https://npmcdn.com/@angular/platform-browser' + ngVer,
    '@angular/platform-browser-dynamic': 'https://npmcdn.com/@angular/platform-browser-dynamic' + ngVer,
    '@angular/http': 'https://npmcdn.com/@angular/http' + ngVer,
    '@angular/router': 'https://npmcdn.com/@angular/router' + routerVer,
    '@angular/forms': 'https://npmcdn.com/@angular/forms' + ngVer,
    '@angular/upgrade': 'https://npmcdn.com/@angular/upgrade' + ngVer,

    // Other libraries
    'rxjs':                       'https://npmcdn.com/[email protected]',
    'angular-in-memory-web-api':  'https://npmcdn.com/angular-in-memory-web-api', // get latest
    'ts':                         'https://npmcdn.com/[email protected]/lib/plugin.js',
    'typescript':                 'https://npmcdn.com/[email protected]/lib/typescript.js',

 };

  //packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { main: 'main.ts',  defaultExtension: 'ts' },
    'rxjs':                       { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
  };    
  var config = {
    // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
    transpiler: 'ts',
    meta: {
      'typescript': {
        "exports": "ts"
      }
    },
    map: map,
    packages: packages
  };
  System.config(config);
})(this);

package.json

{
  "name": "TestApp",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
    "lite": "lite-server",
    "tsc": "tsc",
    "tsc:w": "tsc -w"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@angular/common": "~2.1.2",
    "@angular/compiler": "~2.1.2",
    "@angular/core": "~2.1.2",
    "@angular/forms": "~2.1.2",
    "@angular/http": "~2.1.2",
    "@angular/platform-browser": "~2.1.2",
    "@angular/platform-browser-dynamic": "~2.1.2",
    "@angular/router": "~3.1.2",
    "@angular/upgrade": "~2.1.2",

    "angular-in-memory-web-api": "~0.1.13",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.8",
    "rxjs": "5.0.0-beta.12",
    "systemjs": "0.19.40",
    "zone.js": "^0.6.26"
  },
  "devDependencies": {
    "@types/core-js": "^0.9.34",
    "@types/node": "^6.0.46",
    "concurrently": "^3.1.0",
    "lite-server": "^2.2.2",
    "typescript": "^2.0.3"
  },
  "repository": {}
}
like image 909
Shawn Avatar asked Oct 30 '22 16:10

Shawn


1 Answers

In RC.5 @NgModule was introduced.
You need to declare additional services, modules etc. like this:

import {NgModule} from '@angular/core';
import {LoginComponent} from './login.component';
import {Router,RouterModule} from '@angular/router';
import {FormsModule, FormBuilder} from '@angular/forms';
import {AuthService} from './auth.service';
import {routing} from './app.routing.module';
import {MainComponent} from './main.component';

@NgModule({
  declarations: [LoginComponent], // specify your components here
  imports: [BrowserModule, FormsModule, RouterModule.forRoot([...]), routing],
  providers: [FormBuilder, AuthService, ...], // additional providers
  bootstrap: [MainComponent],
})
class AppModule {}

More info

like image 77
lenny Avatar answered Nov 11 '22 13:11

lenny