0

Attempting a simple HTML TypeScript application and cannot get past this error noted in the subject when attempting to integrate Angularjs into the solution. Basically, I have a simple index.html page as follows:

<!DOCTYPE html>

<html lang="en" ng-app>
<head>
    <meta charset="utf-8" />
    <title>TypeScript HTML App</title>
    <link rel="stylesheet" href="app.css" type="text/css" />
    <script data-require="angular.js@*" data-semver="1.3.13" src="https://code.angularjs.org/1.3.13/angular.js"></script>
    <script src="app.js"></script>
</head>
<body ng-controller="Infrastructure.IndexViewModel">
    <h1>TypeScript HTML App</h1>

    <div id="content"></div>


</body>
</html>

I have created a simple class called IndexViewModel as follows:

module LogsModule { export class LogsViewModel { constructor($scope: ng.IScope, $http: ng.IHttpService) { console.info("logs view model constructed."); } } }

I have also set the Visual Studio setting to ensure that all TypeScript files are combined into a single JavaScript file.

When I run the application, I get the error:

Error: [ng:areq] Argument 'Infrastructure.IndexViewModel' is not a function, got undefined
http://errors.angularjs.org/1.3.13/ng/areq?p0=Infrastructure.IndexViewModel&p1=not%20a%20function%2C%20got%20undefined
    at angular.js:63
    at assertArg (angular.js:1580)
    at assertArgFn (angular.js:1590)
    at angular.js:8431
    at angular.js:7599
    at forEach (angular.js:331)
    at nodeLinkFn (angular.js:7586)
    at compositeLinkFn (angular.js:7078)
    at compositeLinkFn (angular.js:7081)
    at publicLinkFn (angular.js:6957)

I have referenced this and this among others but still confused. What did I miss?

Klaus Nji
  • 18,107
  • 29
  • 105
  • 185

2 Answers2

1

Error clearly says that angular controller is not registered with angular app.

By looking at your code, you didn't created angular module. Thats why you defined ng-app="" as a blank & you are trying to use global funtion. Above angular version 1.3 you need to use angular.module() to define your app, By default global functions are off.

Below is the code to define angular.module

CODE

var app= angular.module('app',[])

app.controller('Infrastructure.IndexViewModel',function($scope){
   //controller code here
});

HTML

<html lang="en" ng-app="app">

Example Plunkr

Update

Brief how Angular JS works on page?

  1. Angular first gets content of html page.
  2. It gather all the angular directives of page like ng-app, ng-init, ng-model,etc.
  3. After that it compiles the page elements using $compile service and directive gets call as per there mentioned priority.(All elements are get loaded on HTML page using $compile service)
  4. At first ng-app directive will execute, It search for mentioned module in our case it is app.(You've this error)
  5. In compilation phase directive compile functions are called (if they exists).
  6. At the time on rendering ng-controller directive load that angular controller.
  7. As controller gets loaded with their DOM, respective directive link function gets call.(If there is any)

Instead of window.load you should use angular.element(document).ready(function() {}) function as like we use document.ready refer link or better inspite use window.onload. While creating app from window.onload you shouldn't mention ng-app="app" on you page, that will break the page, and will give the same error as your getting now (Refere point 4). Use angular.bootstrap to initialize app on page, after declaring all the module, this will initialize angular on page (lazy loading).

Code

//same can be do able with window.onload
  angular.element(document).ready(function() { 
    var app = angular.module('app', []);
      app.controller('Infrastructure.IndexViewModel', function() {
      });
    //bootstraping app on page
    angular.bootstrap(document,['app'])
  });

HTML(Don't mention ng-app)

<div ng-controller="Infrastructure.IndexViewModel">
  <input type="text" ng-model="test" />{{test}}
</div>

And there is no specific way to initialize angular on page, you can use seft executing function or normal adding global functions.

Updated Plukr

Hope this could help you, Thanks.

Community
  • 1
  • 1
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • Where is the most appropriate place to put the initialization code? You example uses the self executing function. I have the same code in window.load event handler and get error that module 'app' is not registered. – Klaus Nji Feb 21 '15 at 23:48
0

I have created a simple class called IndexViewModel as follows: module LogsModule { export class LogsViewModel { constructor($scope: ng.IScope, $http: ng.IHttpService) { console.info("logs view model constructed."); } } }

The class is called LogsViewModel and its in LogsModule. So ng-controller="Infrastructure.IndexViewModel"> should be ng-controller="LogsModule.LogsViewModel">

basarat
  • 261,912
  • 58
  • 460
  • 511