Run angular.js as a callback ($.ajax, for example) - javascript

I'm writing an app with mostly two javascripts, resources_loader.js and app.js, where the first loads some json files used by app.js.
The problem is: app.js (which has angular.js stuff) should run only after resources_loader.js. I tried to run angular code inside the success callback (resources_loader contains a deferred), but this not seems to work well. Here's my index.html:
<!doctype html>
<html ng-app="myapp">
<body>
<script src="angular.js"></script>
<script src="resources_loader.js"></script>
</body>
</html>
Consider that I moved app.js to resources_loader, inside the success callback. Everytime I try to run it, angular raises the following exception: Uncaught Error: No module: myapp.
My guess is that angular.module('myapp', []) should run before onload's event, which is not the case here.
Another thing is that I want to use yepnope.js in my project like this:
<script "yepnope.js"></script>
<script "resources_loader.js"></script>
<script>
var loader = load_stuff();
yepnope({
test: loader.resolved(),
yep: ['angular.js', 'app.js', 'foo.js', 'bar.js'],
nope: ['fail.js']
});
</script>
app.js contains angular code. I think it's more performant because it only loads angular if the resources are loaded. But how can I do it?

Remove ng-app from <html> tag and use angular.bootstrap(document, ['myapp']); to fire it up once your resources are loaded, like this:
var app = angular.module('myapp', []);
app.config(['$routeProvider', '$locationProvider', function($router, $location) {
$location.html5Mode(true);
$router
.when('/', {
templateUrl: 'some_template.html',
controller: 'myController'
});
}]);
// and then, after everything, run
angular.bootstrap(document, ['myapp']);

Related

How to print Hello World in angularjs

I am trying to print Hello World in AngularJS, I have created javascript file named testControllerbut unfortunately it shows this error
here is HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<title>AngularJS</title>
<script type="text/javascript" src="../../app/controllers/testController.js"></script>
</head>
<body ng-app="app">
<div ng-controller="testController">
<h2>{{message}}</h2>
</div>
</body>
</html>
and this testController code
var app = angular.module("app", []);
app.controller("testController", function ($scope) {
$scope.message = "Hello, AngularJS";
});
Where is the issue ? can anyone explain ?
Error clearly stated that testController function haven't got register in app module. There is possibility that there could be more files involved in your application(you have shrink the code to have relevant information in post). It seems in each file you're redefining module every time before registering angular components like below
var app = angular.module("app", []);
app.controller("myOtherController", function ($scope) {
//Code here
});
So in this case what had happened is, app got created once again, and old registered component got wiped out. myOtherController got registered with app module. To fix the issue you should not be declaring module again & again. Define it once and use it in other places.
app.module.js
angular.module('app', []);
testController.js
angular.module("app")
.controller("myOtherController", function ($scope) {
//Code here
});
I could not find anything wrong with you code. So I tried it on works fine for me.
Plunker https://plnkr.co/edit/xSKHe6?p=preview
Check Module Error: https://docs.angularjs.org/error/$injector/nomod?p0=app

Trouble with dynamically loading controllers and views with AngularJS/$controllerProvier and RequireJS

I cam across this blog posting from Dan Wahlin about dynamically loading controllers and views. I downloaded the source from github and tried to reproduce the project on a smaller scale to understand how it all worked. I can get the project to load with the views but where I am stuck is on figuring out why the controller does not seem to bind to the view. Stepping through the code I can see the controller being initialized and injected into the app:
here you can see the app initialize and routes are established
'use strict';
define(['services/routeResolver'], function () {
var app = angular.module('myApp', ['ngRoute', 'ngAnimate', 'ui.bootstrap', 'breeze.angular', 'routeResolverServices']);
app.config(['$routeProvider', 'routeResolverProvider', '$controllerProvider',
'$compileProvider', '$filterProvider', '$provide', '$httpProvider',
function ($routeProvider, routeResolverProvider, $controllerProvider,
$compileProvider, $filterProvider, $provide, $httpProvider) {
app.register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
//From Dan Whalin project comments: route.resolve() now accepts the convention to use (name of controller & view) as well as the
//path where the controller or view lives in the controllers or views folder if it's in a sub folder.
// first param is the name of the controller, second param is the directory it and the view exist in, third param is the alias (controller as) optional third param is true false for security
var route = routeResolverProvider.route;
$routeProvider
.when('/', route.resolve('main', '', 'vm'))
.otherwise({ redirectTo: '/' });
}
]);
////support for lodash
// app.factory('_', ['$window', function ($window) {
// return $window._;
// }]);
// breeze factory manager
app.factory('entityManagerFactory', ['breeze', emFactory]);
function emFactory(breeze) {
// Convert properties between server-side PascalCase and client-side camelCase
breeze.NamingConvention.camelCase.setAsDefault();
// Identify the endpoint for the remote data service
var serviceRoot = window.location.protocol + '//' + window.location.host + '/';
var serviceName = serviceRoot + 'breeze/breeze'; // breeze Web API controller
// the "factory" services exposes two members
var factory = {
newManager: function () { return new breeze.EntityManager(serviceName); },
serviceName: serviceName
};
return factory;
};
app.service("httpDataLoader", ["$http", function ($http) {
this.load = function () {
return $http();
}
}]);
//global filter to allow html to render in the UI and bypass SCE (secure content expression)
//usage: ng-html-bind="properyExpresson | html"
app.filter('html', ['$sce', function ($sce) {
return function (text) {
return $sce.trustAsHtml(text);
}
}
]);
app.run(['breeze', function (breeze) { }]);//currently doing nothing
return app;
});
UPDATE
A question was asked about the route resolver and how it was supposed to work:
From Dan Wahlin Bolg:
The routeResolver.js script creates an AngularJS provider. It’s loaded by RequireJS and used in app.js within the config() function to define routes and resolve them dynamically at runtime.
AngularJS already comes with built-in support for loading views dynamically and with a little more work controllers can be loaded dynamically as well. Loading controller scripts can be done by assigning the resolve property mentioned earlier to a function that handles loading the controller. What’s unique about routeResolver is that it doesn’t accept hard-coded paths to the target view or controller. Instead, you define a base name such as “main” and the resolver will generate the path to the appropriate view and controller based on a standard convention.
within main.js I define the files to load with require
requirejs.config({
baseUrl: 'app',
urlArgs: 'v=1.0',
});
require([
'app',
'services/routeResolver',
'services/config',
'services/dataService'
],
function () {
angular.bootstrap(document, ['myApp']);
});
and within my mainController I setup a basic controller
'use strict';
define(['app'], function (app) {
var injectParams = ['$window', 'dataService'];
var mainController = function($window, dataService){
var vm = this;
vm.message = 'we are wired up';
vm.connect = function () {
alert('hello')
};
};
mainController.$inject = injectParams;
app.register.controller('mainController', mainController);
});
index.html is setup as
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="Content/bootswatch-slate.css" rel="stylesheet" />
<title></title>
</head>
<body ng-cloak>
<div ng-view></div>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/angular-route.min.js"></script>
<script src="Scripts/angular-animate.min.js"></script>
<script src="Scripts/angular-sanitize.min.js"></script>
<script src="Scripts/angular-ui/ui-bootstrap.min.js"></script>
<script src="Scripts/breeze.min.js"></script>
<script src="Scripts/breeze.bridge.angular.js"></script>
<script src="Scripts/require.js" data-main="Scripts/main"></script>
</body>
</html>
and the main view is pretty basic
<div>
<p>static text</p>
<p>{{vm.message}}</p>
<button type="button" ng-click="vm.connect()">click</button>
</div>
What I am seeing in the project is the page/view load fine and within the dev tools I can see the controller as well as all scripts initialize. However the scoped items within the controller vm.message or the function call vm.connect are not bound or recognized from the view. Dev Tools show no error in the console and the view with static content renders. I think I may be getting fooled with the scope of the controllers is either getting duplicated or I am somehow not injecting it correctly. I tried to use the Angular extension to observe the scope and watches but it would error out. I got the same error when I ran the source project from gitHub, but with the angular extension turned off the source project runs fine.
I tried to setup a plnkr but due to the configuration/routing of the project it wouldn't run so here is a link to the full solution from VS. The code is on a GoogleDrive share if I need to move it to another repository please let me know. I would appreciate any code review and suggestion on what I have missed or overlooked. In comparing my code to what is in Dan's solution it appears to be the same.
I'd appreciate any suggestions or ideas
thanks
There were differents between the code in blog post and github.
As routeResolverProvider.route.resolve() on the blog post only support 3 parameters
function (baseName, path, secure) {...}
And on github, it is instead support 4 parameters
function (baseName, path, controllerAs, secure) {...}
So the only possiblily for controllerAs mis-registered with $routeProvider is the code on blog post was used. And routeResolverProvider.route.resolve() is not supporting controllerAs configuration.

Uncaught Error: [$injector:modulerr with angualrJs when i use routing

this is part of my problem = https://jsfiddle.net/2vrz38d6/
it contain just the js part open the console to see what i have
i get confused to solve this error
Error: $injector:modulerr
Module Error
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.3.10/$injector/modulerr?p0=myApp&p1=Error%3A%…3A9641%2Fassets%2Fglobal%2Fplugins%2Fangularjs%2Fangular.min.js%3A38%3A435)
My Error happen with routing in angularJs
the error which i took it is :
my Error page here
my code is :
(function () {
var MyApp = angular.module('myApp');
MyApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/expenses.html',
controller: 'CurriculumController'
})
.otherwise({
redirectTo: '/'
});
and the controller
MyApp.controller('CurriculumController', ['$scope', '$rest', function ($scope, $rest) {
//some stuf here
for my script angular file :
in the first i have this
<script src="/assets/global/plugins/angularjs/angular.min.js"></script>
and in the middle of the project i have
the file of my angular apps
<script src="/Scripts/NGModel/Curriculum/Curriculum.js"></script>
and after that the file of the routing part for angularjs
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.min.js"></script>
As people above have suggested, you need to include that file, but you also need to make sure that you are doing it in the correct order as well in your index file. I suppose trying a different set of CDNs wouldn't hurt either.
<script src="https://code.angularjs.org/1.3.15/angular.min.js"></script>
<script src="https://code.angularjs.org/1.3.15/angular-route.min.js"></script>
Also, in your route configurations, just a mention that you can do this as well for your otherwise:
MyApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/expenses.html',
controller: 'CurriculumController'
})
.otherwise("/");
});
you have to include angular-route.js.
Dependency injection would be angular.module('myApp', ['ngRoute']);
EDIT as the inclusion of Angular libraries were updated in the OP's problem statement :-
Replace
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.min.js"></script> with
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.10/angular-route.min.js"></script> as you have mentioned in comments that you are using v1.3.10
And as #Garrett has suggested, add,
.otherwise("/");
You will need to make this work:
1) Add the angular-route file:
Include the file below the angular.js
<script src="angular-route.js">
2) Inject the ng-route at the definition of your app:
angular.module('myApp', ['ng-route']);
you should add your dependencies in to the module like this
var app = angular.module('myApp', ['ngRoute']);

AngularJS Separating The Controllers, Argument is not a function, it is undefined

I know it is asked hundreds of times, but I cannot really find out the error. I have looked all the similar questions At first, I did everything in one page, it was working, but obviously I needed to learn to separate my controllers to different files. I have did the following:
partials/hosts.html:
Hosts Page
<div ng-controller="HostsCtrl">
{{ title }}
</div>
index.html
<html>
<head>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap.min.js"></script>
<script src="js/myApp.js"></script>
<script src="js/HostsCtrl.js"></script>
</head>
<body ng-app="MyApp">
...
js/MyApp.js
Create MyApp module, and a submodule named controllers
var app = angular.module('MyApp', ['ngRoute', 'ui.bootstrap']);
console.log("index.js file loaded");
angular.module('MyApp.controllers', []);
js/HostsCtrl.js
Just a simple controller in MyApp.controllers module that displays hello world and time.
console.log("HostsCtrl.js file loaded");
angular.module('MyApp.controllers').controller("HostsCtrl", function($scope) {
$scope.title = "Hello world" + new Date().getTime();
});
The console output:
index.js file loaded MyApp.js:2
HostsCtrl.js file loaded HostsCtrl.js:1
Error: [ng:areq] Argument 'HostsCtrl' is not a function, got undefined
I assume the loading order is correct, however I do not understand why it gives an error and cannot resolve HostsCtrl. What am I doing wrong?
Looks like you never declare MyApp.controllers dependency (since your controllers are in separate module). Try this:
var app = angular.module('MyApp', [
'ngRoute',
'ui.bootstrap',
'MyApp.controllers'
]);

Angular module config not called

I'm trying to get my head around AngularJS and ran into a problem.
var myApp = angular.module('myApp', ['myApp.services']);
myApp.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
console.log('Configuring module "myApp"');
$routeProvider.when('/dashboard', {templateUrl: 'partial/dashboard', controller: DashboardController});
$routeProvider.when('/menu', {templateUrl: 'partial/other', controller: OtherController});
$routeProvider.otherwise({redirectTo: '/dashboard'});
$locationProvider.html5Mode(true);
}]);
To my understanding the configuration function should be called when the module gets loaded. But it does not!
I have the ng-app="myApp" directive on the <body> tag. And scripts loaded just before the body closing tag in the correct order (as far as that matters).
<script src="angular.js"></script>
<script src="app.js"></script>
<script src="services.js"></script>
<script src="controllers.js"></script>
</body>
I'm pretty sure I must be overlooking something trivial here. There should be a message printed to the console. But it remains empty with no errors or warnings whatsoever.
The parts of the app not depending on the routes runs just fine.
Update: simplified version of my service.js
'use strict';
angular.module('myApp', function ($provide) {
$provide.factory('myService', function ($http) {
var service = function () {
...
service implementation
...
};
return new service();
});
});
It seems that the method I used for defining the service was overriding my myApp module.
This is the overriding line
angular.module('myApp', function ($provide) ...
This code simply redefines the myApp module and adds a function to configure that one.
I refactored service.js to this simplified version and it started to work.
var myApp = angular.module('myApp');
myApp.factory('securityService', function () {
return SomeFancyServiceObject();
});
I was missing ng-app="myApp" inside my html tag - and I realized this while reading your question :-)
I usually see routing applied by chaining them together:
$routeProvider
.when('/dashboard', {templateUrl: 'partial/dashboard', controller: DashboardController})
.when('/menu', {templateUrl: 'partial/other', controller: OtherController})
.otherwise({redirectTo: '/dashboard'});
Can't see why yours would not work, but might be worth a go.

Categories

Resources