Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp - angularjs

Uncaught Error: [$injector:modulerr] Failed to instantiate module
myApp due to: Error: [$injector:nomod] Module 'myApp' is not
available! You either misspelled the module name or forgot to load it.
If registering a module ensure that you specify the dependencies as
the second argument.
Good day, before I asked this question, I looked through all the previous answers to this question as well as went through documentation, unfortunately non did help me that is why I am asking.
This is the how I am using angular and controller:
html file:
<!DOCTYPE html>
<html>
<head>
</head>
<body ng-app="myApp">
<div ng-controller="login.controller">
<input ng-model="foodDescription">
<button ng-click="onSomethingChanged(foodDescription)">Do Something</button>
<h1>The Food is {{viewModel.foodDescription}}</h1>
</div>
<script type='text/javascript' src="./node_modules/angular/angular.js"></script>
<script type='text/javascript' src="./module.js"></script>
</body>
</html>
Module file:
import angular = require('angular');
import loginControllerImport = require('./Views/login/login.Controller');
var app: angular.IModule = angular.module("myApp", []);
app.controller(loginControllerImport.name, loginControllerImport.loginController);
loginControllerImport.loginController.$inject = ['$scope'];
export = app;
Controller file:
import angular = require('angular');
import loginViewModelImport = require('./login.viewModel');
export interface ILoginControllerScope extends angular.IScope {
viewModel: ILoginViewModel;
onSomethingChanged: (myFood: string) => void;
}
export class loginController {
constructor(private $scope: ILoginControllerScope) {
this.$scope.viewModel = new loginViewModelImport.loginViewModel();
this.$scope.onSomethingChanged = this.onSomethingChanged.bind(this);
}
private onSomethingChanged(myFood: string) {
this.$scope.viewModel.foodDescription = myFood;
}
}
export var name: string = "login.controller";
View Model file:
export class loginViewModel implements ILoginViewModel {
private _foodDescription: string;
get foodDescription(): string {
return this._foodDescription;
}
set foodDescription(value: string) {
this._foodDescription = value;
}
}
So what would be the problem for this error to appear? Why is it appearing? how can I fix it? How can I avoid it in the future?
Many thanks.

Since you use require() to load your dependencies, you should also a) bundle them into one output file, b) load them manually or c) load them with a library like RequireJS. I cannot verify if module.js is your bundle file, otherwise this code won't succeed unfortunately.
If I would face this problem myself, I would strip down the app to the bare minimum (just load the myApp module itself) and get that one working. After getting this spinning up, add your view models and controllers (tip: one by one).

Related

AngularJS can't find components when using IIFEs

The angularjs style guide recommends using IIFEs to wrap angular components. However when I try to wrap mine as per the example, I run into the problem of them being "hidden" from angularjs and it is unable to load them
page.html
<script type="text/javascript" src="my-module.js" %}"></script>
<script type="text/javascript" src="my-module-controller.js" %}"></script>
<div ng-app="my.app" ng-controller="MyAppController">
{{ somevar }}
</div>
my-app.js
(function() {
'use strict';
angular
.module('my.app', []);
});
my-app-controller.js
(function() {
'use strict';
angular
.module('my.app')
.controller('MyAppController', MyAppController);
function MyAppController() {
....
}
});
This results in the error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module my.app due to:
Error: [$injector:nomod] Module 'my.app' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
If I remove the IIFE on the module declaration so I'm left with the following:
'use strict';
angular
.module('my.app', []);
It works, to the extent that the next error is:
Error: [ng:areq] Argument 'MyAppController' is not a function, got undefined
If I remove the IIEF from the controller definition, everything works as expected.
This is obviously a stripped down example, in the real project I am serving this page from a Django server, though I can't tell if that's relevant or not.
Those are not IIFE's. You are not invoking the function. End with }()); or })();
(function() {
'use strict';
angular
.module('my.app')
.controller('MyAppController', MyAppController);
function MyAppController() {
....
}
})();

Simple Example Using Angular 1 with TypeScript and SystemJS

I have been trying to convert a TypeScript Angular 1 application to use ES6 style module imports.
Dropping the use of namespace and using the import keyword to pull in modules. e.g.
import * as angular from "angular";
import * as angularroute from "angular-route";
But I have run into some issues.
I'm getting an error from angular:
Uncaught (in promise) Error: (SystemJS) [$injector:modulerr] Failed to instantiate module testApp due to:
Error: [$injector:modulerr] Failed to instantiate module ngRoute due to:
Error: [$injector:nomod] Module 'ngRoute' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument
To illustrate the issue, I have created two applications on github:
1) Angular1WithNamespaces- Original app that I want to convert.
2) Angular1WithSystemJS - My Conversion, that has an issue.
Below are snippets from the Angular1WithSystemJS example that has the issue.
index.html
<!DOCTYPE html>
<html lang="en" ng-app="testApp">
<head><base href="/"></head>
<body >
<ng-view></ng-view>
<script src="node_modules/systemjs/dist/system.js"></script>
<script src="configs/systemjs.config.js"></script>
<script>
System.import('app/boot');
</script>
</body>
</html>
systemjs.config.js
System.config({
defaultJSExtensions: true,
paths: {
"npm:*": "../node_modules/*"
},
// map tells the System loader where to look for things
map: {
"angular": "npm:angular/angular.js",
"angular-route": "npm:angular-route/angular-route.js",
},
meta: {
'angular': {
format: 'global',
},
'angular-route': {
format: 'global',
},
}
});
boot.ts
/// <reference path="../typings/tsd.d.ts" />
import * as angular from "angular";
import * as angularroute from "angular-route";
let main = angular.module("testApp", ["ngRoute"]);
main.config(routeConfig)
routeConfig.$inject = ["$routeProvider"];
function routeConfig($routeProvider: angular.route.IRouteProvider): void {
$routeProvider
.when("/dashboard", {
templateUrl: "/app/dashboard.html",
})
.otherwise("/dashboard");
}
Any help getting this working would be greatly appreciated.
I have found a solution by reading a blog post from https://legacy-to-the-edge.com/2015/01/21/using-es6-with-your-angularjs-project/
It was related to how I did the import for angular-route.
In the end it was just a one-liner change.
In boot.ts I changed the import statement from:
import * as angularroute from "angular-route";
to:
import "angular-route";
I can only assume, that the latter will also run scripts in the module file.
According to the spec on import at developer.mozilla.org
import "my-module";
Import an entire module for side effects only, without importing any bindings.
The fixed version is in github Angular1WithSystemJSFixed

Pass json object on page to Angular2 component

I understand that services are the preferred way to get data into an app. However, what it the data is already on the page as js variable. Essentially looking for how you’d do the following with Angular:
var foo = {key1:value2, key2:value2};
myInitFunction( foo );
// This function may be on the page or in an external doc
myInitFunction( foo ){
// Do stuff with foo…
}
Essentially, foo exists on page load as a server-side object already. It seems silly to me to make an Ajax call to get this information (again). Foo could exist elsewhere like:
<span data-foo="{key1:value2, key2:value2}}></span>
If that makes getting the data into my app easier…
An easy way to do it is to store it as a global variable in your index.html for example :
<html>
<head>
<title>Angular QuickStart</title>
<!-- BASIC ANGULAR 2 INDEX HTML -->
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<body>
<my-app>Loading...</my-app>
<script>
// Store your value in some global scope variable.
window.foo = {key1:'value2', key2:'value2'};
</script>
</body>
</html>
And then, you can wrap this value in some Angular2 service
#Injectable()
export class FooService {
getFoo() {
return window.foo;
}
}
I assume this span is on your initial html page when you bootstrap your app(main) module, if so then you can do some jquery and assign this value to a global variable. (such as
var meyVar = $('#mySpan').attr('data-foo')
)
and then in your angular component you declare myVar and you can access it.
declare _myVar;
alert(_myvar)
I think the solution would be a custom value provider, then you can use dependency injection with it within your application. Check out:
https://angular.io/docs/ts/latest/guide/dependency-injection.html
In your index.html:
<script>
window.config = {key1:value2, key2:value2};
</script>
And then in your app.module
import { OpaqueToken } from '#angular/core';
export let APP_CONFIG = new OpaqueToken('app.config');
/* ... */
#NgModule({
/* ... */
providers: [{ provide: APP_CONFIG, useValue: window.config }]
})
class AppModule {}

Meta tags (i.e <title>) in Meteor + Angular-Ui-Router

Is there any way that meta tags could be either controlled by or included in Angular templates with Angular-Ui-Router?
In Meteor Angular your app cannot be wrapped like this: <html ng-app="app">, it has to be at least <body ng-app="app"> to work - Meteor looks after all CSS and JS dependecies. Therefore your Angular app has no way to access the <head> (say with $rootScope).
Without Angular-Ui-Router you can simply add (partyDetails.html):
<head>
<title>Details of party {{}}</title>
</head>
in your template, which doesn't work with Ui-Router, I get:
Error: Cannot find module './partyDetails.html'
Error: [$injector:modulerr] Failed to instantiate module app due to:
[$injector:nomod] Module 'app' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
It's OK after I remove <head> tag.
I need to have tags dynamic (like mentioned <title></title> but not only!) on my website - is it actually possible?
I managed to use yasinuslu:blaze-meta. Your component controller:
import angular from 'angular';
import angularMeteor from 'angular-meteor';
import uiRouter from 'angular-ui-router';
import { Meteor } from 'meteor/meteor';
import { Meta } from 'meteor/yasinuslu:blaze-meta';
//..
class PartyDetailsCtrl {
constructor($stateParams, $scope) {
'ngInject';
//..
Meta.config({
options: {
title: "Default Title",
suffix: "Socially",
separator: " — "
}
})
Meta.set({
name: 'name',
property: 'description',
content: 'Meta description'
});
Meta.setTitle("Party Details");
}
//..
}
//..
I believe Meta.config({}) could be placed in .run block of your app. Hope that helps!

Angular 2 Router instantiation issue

I have an issue with the Angular 2 Router. I want basically to be able to navigate through my app with a function so I wanna use the navigate function from the Router, like in the official example.
So here is what I have in my files :
index.html
<script src='#routes.Assets.versioned("lib/typescript/lib/typescript.js")'></script>
<script src='#routes.Assets.versioned("lib/es6-shim/es6-shim.min.js")'></script>
<script src='#routes.Assets.versioned("lib/angular2/bundles/angular2-polyfills.js")'></script>
<script src='#routes.Assets.versioned("lib/angular2/es6/dev/src/testing/shims_for_IE.js")'></script>
<script src='#routes.Assets.versioned("lib/systemjs/dist/system.js")'></script>
<script src='#routes.Assets.versioned("lib/rxjs/bundles/Rx.js")'></script>
<script src='#routes.Assets.versioned("lib/angular2/bundles/angular2.dev.js")'></script>
<script src='#routes.Assets.versioned("lib/angular2/bundles/http.js")'></script>
<script src='#routes.Assets.versioned("systemjs.config.js")'></script>
<script src='#routes.Assets.versioned("lib/angular2/bundles/router.dev.js")'></script>
and in the typescript file where I want to use navigate :
import { Http } from "angular2/http"
import { Router } from "angular2/router"
export class ClassName {
constructor (private _http: Http, private _router: Router) {}
goSomewhere(pageName: string) {
let link = [pageName]
this._router.navigate(link)
}
}
It's basically this, I tried to undo and add step by step, and the import worked and then it failed when adding it to the constructor, removing private or renaming the variable didn't work either.
On my imports I used to have angular2.js and router.js and got this issue :
angular2-polyfills.min.js:1 Error: EXCEPTION: Error during instantiation of t! (e -> t).
but I found here it could fix the issue by using the dev libs, but now I have this :
angular2-polyfills.min.js:1 Error: EXCEPTION: Error during instantiation of ApplicationRef_! (ApplicationRef -> ApplicationRef_).
Now I'm a bit lost... For information I'm using the beta 17 version of Angular 2.
So I found a way to make it work. We cannot use Router in a constructor of an #Injectable with no #RoutesConfig, so to keep the logic I wanted, I made this in my injectable class :
doSomething(router: Router, foo: any) {
//instructions with set of link variable
router.navigate(link)
}
and now I just have to add the injectable class and the router in all my components constructors and use _className.doSomething(this._router, foo) to use the function
Hope it will help some others :)

Resources