I'm trying to get route parsing for $routeProvider to generate .when()'s from array. Here is the code in app.js that I've tried. This generates correct routes, but causes infinite loops of "Tried to load AngularJS more than once". I only load angularjs in the index. html file, into which the view is rendered. How can I get routes from array to work? Array structure is "route":"fileName.html".
var dynape = angular.module("dynape",['ngRoute','dynape.controllers','dynape.services','ngCookies']);
dynape.config(['$routeProvider','$locationProvider',
function($routeProvider,$locationProvider) {
var db = new PouchDB('http://localhost:5984/siteconf', {skipSetup: true});
db.get("pages").then(function(doc) {
var tmp = doc;
delete tmp["_id"];
delete tmp["_rev"];
delete tmp["/"];
for(p in tmp) {
console.log(p.toString());
$routeProvider.when(p.toString(), {
controller: "SiteController",
templateUrl: "views/pages/"+tmp[p]
});
}
});
// Follwing routes never change
$routeProvider.when("/",{
controller: 'SiteController',
templateUrl: "views/frontPage.html"
}).when("/admin",{
controller: 'AdminLoginController',
templateUrl: "views/admin/login.html"
}).when("/admin/setup", {
controller: 'SetupController',
templateUrl: "views/admin/setup.html"
}).when("/admin/dashboard", {
controller: 'AdminActionController',
templateUrl: "views/admin/dashboard.html"
}).when("/admin/pages", {
controller: 'AdminActionController',
templateUrl: "views/admin/pages.html"
}).otherwise({
redirectTo: "/"
});
$locationProvider.html5Mode(true);
}
]);
angular.module("dynape.controllers",[]);
angular.module("dynape.services",[]);
The index.html into which I render the view:
<!DOCTYPE html>
<html ng-app="dynape">
<head>
<base href="/">
<meta charset="utf-8">
<title>A Dynape Site</title>
<link rel="stylesheet" href="/css/base.css" media="screen">
<link rel="stylesheet" href="/css/components-base.css" media="screen">
<link rel="stylesheet" href="/css/gridsys.css" media="screen">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
</head>
<body>
<div class="wrap" ng-view>
</div>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5.js"></script>
<script type="text/javascript" src="src/vendor/jquery.js"></script>
<script type="text/javascript" src="src/vendor/pouchdb.min.js"></script>
<script type="text/javascript" src="src/vendor/image-picker.min.js"> </script>
<script type="text/javascript" src="src/vendor/angular.min.js"></script>
<script type="text/javascript" src="src/vendor/angular.route.min.js"></script>
<script type="text/javascript" src="src/vendor/angular-cookies.js"></script>
<script type="text/javascript" src="src/app.js"></script>
<script type="text/javascript" src="src/services/AuthenticationService.js"></script>
<script type="text/javascript" src="src/controllers/AdminLoginController.js"></script>
<script type="text/javascript" src="src/controllers/AdminActionController.js"></script>
<script type="text/javascript" src="src/controllers/SetupController.js"></script>
<script type="text/javascript" src="src/controllers/SiteController.js"></script>
</body>
</html>
You can't access $routeProvider outside of .config
My guess would be that db.get is a call to your server which runs async. Then, by the time that call comes back, the routeProvider is already registered.
In other words, your code is being executed in the following order:
Create app (groovy)
Call CONFIG with $routeProvider (swell)
Call db.get(<callback>) (fine)
Manually setup $routeProvider.when with 6 specific routes (awesome)
.... Now, angularJs has been bootstrapped ...
db.get returns from the server and calls <callback> (uh-oh)
Attempting to access/change $routeProvider with new 'dynamic' routes (oops)
2 Potential Solutions:
A. bootstrap/config angularJs AFTER the db.get() returns. Never tried this ... I guess it could work, but seems risky.
B. DEFER route configuration using a decorator. there is an excellent blog post on this topic which seems to do what you want to do.
It would mean that all your dynamic routes would need the same "root" (eg - they all follow the format "/other/:route*"), but that's the only restriction.
I'd go with option B. Seems like a good plan!
Related
I want to bundle all of my controllers in same module say app.core but it results in undefined.
app.js
angular.module('app',['ui.router','app.routes','app.core']);
app.core.js
angular.module('app.core', []);
sidebar.ctrl.js
angular.module('app.core',['ui.router','ui.bootstrap'])
.controller('SidebarController',function($scope,$uibModal){
$scope.login=function(){
$uibModal.open({
templateUrl:'./partials/login/login.modal.tpl.html',
size:'sm',
controller:'LoginController'
});
}});
login.ctrl.js
angular.module('app.core',['ui.router','ui.bootstrap'])
.controller('LoginController',function($scope){
$scope.closeLoginModal=function(){
$uibModalInstance.dismiss('cancel');
}});
index.html
<script type="text/javascript" src="app.core.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="partials/sidebars/sidebar.ctrl.js"></script>
<script type="text/javascript" src="partials/login/login.ctrl.js"></script>
When I run with above sequence of loading js files it gives Argument 'SidebarController' is not a function got undefined but when I comment login.ctrl.js script it gives no error but when opening login modal results in 'LoginController' is not a function got undefined.
Any help would be appreciated.
Try this instead :
angular.module('app',['ui.router','ui.bootstrap', 'app.routes','app.core']);
angular.module('app.core', ['app']);
angular.module('app.core')
.controller('LoginController',function($scope){
$scope.closeLoginModal=function(){
$uibModalInstance.dismiss('cancel');
}});
and try this order :
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="app.core.js"></script>
<script type="text/javascript" src="partials/sidebars/sidebar.ctrl.js"></script>
<script type="text/javascript" src="partials/login/login.ctrl.js"></script>
I want to use this method (which ouputs a message if a user is typing) with a service. the method is updating a info varible (set its text to "typing" or blank).
I thought about using this method as a service to my angular model. the problem is that this method needs access to the text varible {{info}} with sits inside the view (some html).
How can I do that?
my code is below....
Thanks
js file
mymodule.controller("cntrlChat", ['$scope','isUserTypingService',
function($scope,isUserTypingService){
$scope.isUserTyping=function(){
isUserTypingService($scope.info);
}
}]);
mymodule.factory('isUserTypingService',['$q','$timeout', function($q,$timeout) {
var isUserTyping= function(info) {
runTwoFunctionWithSleepBetweenThem(function (){info='user is typing...';},function (){info='';},3500);
};
var runTwoFunctionWithSleepBetweenThem=function(foo1, foo2, time) {
$q.when(foo1()).then(() => $timeout(foo2, time));
}
return isUserTyping;
}]);
index.html
<html>
<head>
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9">
</script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" type="text/css" href="../css/style.css">
</head>
<div ng-app="mymodule" ng-view>
</div>
</html>
chat.html
{{info}}
you could do something like this:
<input ng-model="userInput" ng-change="runWhenTyping()" />
in your controller:
$scope.userInput = '';
$scope.runWhenTyping = function () { isUserTypingService($scope.userInput) }
Each time they type runWhenTyping will be called and in turn it will call your service.
I have this main application called dashboard and I want to inject a custom made module called core.
I keep getting this injection error and I have no idea why. I am following a template that my co-worker has and it is pretty much word for word so I do not know why it is not working for me.
app.js
(function(){
'use strict';
var dependencies = [
'ngRoute',
'core'
]; // all our modules
angular.module('dashboard', dependencies).config(Config); //.config(Config);
Config.$inject = ['$locationProvider'];
function Config($locationProvider){
$locationProvider.hashPrefix('!');
}
angular.element(document).ready(function(){
angular.bootstrap(document, ['dashboard']);
});
})();
layout.hbs
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<link rel='stylesheet' href='/javascripts/bootstrap/dist/css/bootstrap.css' />
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<div class="flud-container">
{{{body}}}
</div>
</body>
<!-- JS Libraries -->
<script type='text/javascript' src='/lib/jquery/dist/jquery.min.js'></script>
<script type='text/javascript' src='/lib/bootstrap/dist/js/bootstrap.min.js'></script>
<script type='text/javascript' src='/lib/angular/angular.min.js'></script>
<script type='text/javascript' src='/lib/angular-route/angular-route.min.js'></script>
<script type='text/javascript' src='/modules/core/core.client.module.js'></script>
<script type='text/javascript' src='/modules/core/config/core.client.routes.js'></script>
<script type='text/javascript' src='/app.js'></script>
</html>
core.client.module.js
(function(){
'use strict';
// var dependencies = [
// ];
angular.module('core', []);
angular.module('core').run(intialize);
initialize.$inject = ['$rootScope', '$location'];
function intitialize($rootScope, $location){
//initialize module's variables here
}
});
console error:
angular.js:38 Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.5.3/$injector/modulerr?p0=dashboard&p1=Error%…(http%3A%2F%2Flocalhost%3A3000%2Flib%2Fangular%2Fangular.min.js%3A20%3A463)
As you were using IIFE pattern for restricting the scope of code, you should invoke function of core.client.module.js immediately to core module get available.
core.client.module.js
(function(){
//---- code here-----//
})(); //<---invoke the function
Here is the structure:
Here are the sources:
/* #flow */
"use strict";
(function () {
const app = angular.module('Lesson2', ['ngRoute', 'ngAnimate'] );
app.config(function($routeProvider){
$routeProvider
.when('/what', { controller:'FavoCtrl', templateURL:'pages/what.html'})
.when('/where', { controller:'FavoCtrl', templateURL:'pages/where.html'})
.otherwise({redirectTo:'/what'});
});
app.controller('FavoCtrl', function ($scope) {
$scope.favouriteThings=[
{what:'raindrops', by:'on', where:'roses'},
{what:'whiskers', by:'on', where:'mittens'},
{what:'Brown paper packages', by:'tied up with', where:'strings'},
{what:'schnitzel', by:'with', where:'noodles'},
{what:'Wild geese', by:'that fly with', where:'the moon on their wings'},
{what:'girls', by:'in', where:'white dresses'},
{what:'Snowflakes', by:'that stay on', where:'my nose and eyelashes'}
];
})
})();
<!DOCTYPE html>
<html ng-app="Lesson2">
<head lang="en">
<link rel="stylesheet" type="text/css" href="styles/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
<script src="scripts/app.js"></script>
<meta charset="UTF-8">
<title>Lesson 2</title>
</head>
<body>
Hello!
<ng-view></ng-view>
</body>
</html>
And two "what.html" and "where.html" are plain texts, like This is "where.html"
The hardest thing here is that browser does not throw any error, console is clean. Views are not loaded, all I see is "Hello" of "index.html"
Seems like you have a typo, in your config block, use templateUrl instead of templateURL.
It should look like:
app.config(function($routeProvider){
$routeProvider
.when('/what', { controller:'FavoCtrl', templateUrl:'pages/what.html'})
.when('/where', { controller:'FavoCtrl', templateUrl:'pages/where.html'})
.otherwise({redirectTo:'/what'});
});
First you have a typo in your route configuration, it is "templateUrl" and not "templateURL".
If this doesn't solve your problem try adding the controller in your index.html
<html ng-app="Lesson2" ng-controller="FavoCtrl">
I'm using jquery bxslider on my first angular project. It is not working with template inside ng view. If use this one without ng view means it is working.
This is my HTML page:
<!doctype html>
<html ng-app="appSathya">
<head>
<meta charset="utf-8">
<title>Modest</title>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400italic,600italic,700italic,400,600,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/bootstrap.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/jquery.bxslider.css">
</head>
<body>
<header ng-include='"template/header.html"'></header>
<section ng-view></section>
<script src="js/angular.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="js/jquery-1.9.1.js"></script>
<script src="js/jquery.bxslider.js"></script>
<script src="js/main.js"></script>
</body>
</html>
and this is my javascript file
// JavaScript Document
var app = angular.module('appSathya', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
// Home
.when("/", {templateUrl: "partials/home.html", controller: "PageCtrl"})
}]);
app.controller('menuController', function($scope){
$scope.menus = [
{mitem:"Home", murl:"#/link"},
{mitem:"About", murl:"#/link"},
{mitem:"Work", murl:"#/link"},
{mitem:"Team", murl:"#/link"},
{mitem:"Services", murl:"#/link"},
{mitem:"Features", murl:"#/link"},
{mitem:"contact", murl:"#/link"}
];
});
app.directive('startslider',function() {
return {
restrict: 'A',
replace: true,
template: '<ul class="bxslider">' +
'<li ng-repeat="picture in pictures">' +
'<img ng-src="{{picture.src}}" alt="" />' +
'</li>' +
'</ul>',
link: function(scope, elm, attrs) {
elm.ready(function() {
$("." + $(elm[0]).attr('class')).bxSlider({
mode: 'fade',
pager: false,
autoControls: true
});
});
}
};
});
app.controller('PageCtrl', function($scope) {
$scope.pictures = [
{src:'img/banner.jpg' },
{src:'img/banner.jpg' },
{src:'img/banner.jpg' }
];
});
Change you order of script includes to this below:
<script src="js/jquery-1.9.1.js"></script>
<script src="js/angular.js"></script>
the reason that your code may malfunction angular has it's own version of jqlite and strips certain namespaces and attributes... but if you change the order angular has a function that recognize if jquery calls supercede the angular versions.
If all you need is to use a jQuery plugin inside Angular, then
the jQuery Passthrough directive should do it.
First include JQuery before AngularJS, then in jquery code use jQuery instead of $ since angular also uses $.
Some plugins not directly work with Angular. Ex:- Flexslider has separate JS which is compatible with AngularJS.
Here, you can solve your problem by looking at here
Have you tried placing your script src links in the header? Sure, it's sometimes required to place them in the footer, but if you want them to fire before anything else, play about with the order. Looking at the code, I'd suggest placing your <script src="js/jquery-1.9.1.js"></script><script src="js/jquery.bxslider.js"></script> tags in the head?