I'm trying to use Angular UI modal, but I keep getting an unknown provider error message: "Error: [$injector:unpr]".
I use custom build to minimize the overall size of the file. I have injected the ui dependency in the app when creating it. The build files are added to the index.html page.
//This is the app.js file
(function() {
angular.module('locatorApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']);
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home/home.view.html',
controller: 'homeCtrl',
controllerAs: 'vm'
})
.when('/about', {
templateUrl: '/common/views/genericText.view.html',
controller: 'aboutCtrl',
controllerAs: 'vm'
})
.when('/location/:locationid', {
templateUrl: '/locationDetail/locationDetail.view.html',
controller: 'locationDetailCtrl',
controllerAs: 'vm'
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
}
angular
.module('locatorApp')
.config(['$routeProvider', '$locationProvider', config]);
})();
//This is the controller file
(function() {
angular
.module('locatorApp')
.controller('locationDetailCtrl', locationDetailCtrl);
/*Inject $routeParams service into controller to protect from minification*/
locationDetailCtrl.$inject = ['$routeParams', '$uibModal', 'locatorData'];
function locationDetailCtrl($routeParams, $uibModal, locatorData) {
var vm = this;
vm.locationid = $routeParams.locationid;
locatorData.locationById(vm.locationid)
.success(function(data) {
vm.data = {
location: data
};
vm.pageHeader = {
title: vm.data.location.name
};
})
.error(function(e) {
console.log(e);
});
vm.popupReviewForm = function() {
alert("Let's add a review");
};
}
})();
<!-- This is the index.html file-->
<!DOCTYPE html>
<html ng-app="locatorApp">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LocatoR</title>
<link rel="stylesheet" href="/bootstrap/css/amelia.bootstrap.css">
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body ng-view>
<script src="/angular/angular.min.js"></script>
<script src="/lib/angular-route.min.js"></script>
<script src="/lib/angular-sanitize.min.js"></script>
<script src="/lib/ui-bootstrap-custom-2.5.0.min.js"></script>
<script src="/lib/ui-bootstrap-custom-tpls-2.5.0.min.js"></script>
<script src="/angular/locator.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/
jquery.min.js"></script>
<script src="/bootstrap/js/bootstrap.min.js"></script>
<script src="/javascripts/validation.js"></script>
</body>
</html>
//This is the locatorData service
(function() {
/*Data service for pulling data from the API*/
locatorData.$inject = ['$http'];
function locatorData($http) {
var locationByCoords = function(lat, lng) {
return $http.get('/api/locations?lng=' + lng + '&lat=' + lat + '&maxdist=20');
};
var locationById = function(locationid) {
return $http.get('/api/locations/' + locationid);
};
return {
locationByCoords: locationByCoords,
locationById: locationById
};
};
angular
.module('locatorApp')
.service('locatorData', locatorData);
})();
you should use ng-view on a div inside <body>, so script tags will exist after route template is substituted. Then it would be better to reorganize order of script tags you are adding.
At first non-angular script files, then angular, then your sources
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="/javascripts/validation.js"></script>
<script src="/bootstrap/js/bootstrap.min.js"></script>
<script src="/angular/angular.min.js"></script>
<script src="/angular/locator.min.js"></script>
<script src="/lib/angular-route.min.js"></script>
<script src="/lib/angular-sanitize.min.js"></script>
<script src="/lib/ui-bootstrap-custom-2.5.0.min.js"></script>
<script src="/lib/ui-bootstrap-custom-tpls-2.5.0.min.js"></script>
Then use $uibModal service that you've injected:
vm.popupReviewForm = function() {
$uibModal.open({
template: '...html',
//...config from docs
}).then(function(){console.log('closed successfully');})
.catch(function(){console.log('dismissed modal');});
};
Move your script tag either to below of head tag.
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LocatoR</title>
<link rel="stylesheet" href="/bootstrap/css/amelia.bootstrap.css">
<link rel="stylesheet" href="/stylesheets/style.css">
// Scripts
</head>
or, outside the ng-view :
<body>
<div ng-view></div>
// scripts here
</body>
Ok, I've finally figured it out. The problem was using incompatible versions of Angular JS and Angular UI.
Related
I want to load or resources in my header with require.js. How can i do this? Here is my current code for my controller and index. I am new to angularjs and will appreciate your help in solving this challenge.
Require.js: located in js/require.js
require.config({
baseUrl: "js",
paths: {
'angular': '.../lib/angular.min',
'angular-route': '.../lib/angular-route.min',
'angularAMD': '.../lib/angular-animate.min.js'
},
shim: { 'angular-animate.min': ['angular'], 'angular-route': ['angular'] },
deps: ['app']
});
Index.html:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>App Demo</title>
<script data-main="js/main" src="js/require.js"></script>
<script src="js/controllers.js"></script>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="main" ng-view></div>
</body>
</html>
App.js:
define(function () {
var myApp = angular.module('myApp', [
'ngRoute',
'artistControllers'
]);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/list', {
templateUrl: 'partials/list.html',
controller: 'ListContrIndex.htmloller'
}).
when('/details/:itemId', {
templateUrl: 'partials/details.html',
controller: 'DetailsController'
}).
otherwise({
redirectTo: '/list'
});
}]);
return app;
});
Controller.js:
define(['app'], function (app) {
var artistControllers = angular.module('artistControllers', ['ngAnimate']);
artistControllers.controller('ListController', ['$scope', '$http', function($scope, $http) {
$http.get('js/data.json').success(function(data) {
$scope.artists = data;
$scope.artistOrder = 'name';
});
}]);
artistControllers.controller('DetailsController', ['$scope', '$http','$routeParams', function($scope, $http, $routeParams) {
$http.get('js/data.json').success(function(data) {
$scope.artists = data;
$scope.whichItem = $routeParams.itemId;
if ($routeParams.itemId > 0) {
$scope.prevItem = Number($routeParams.itemId)-1;
} else {
$scope.prevItem = $scope.artists.length-1;
}
if ($routeParams.itemId < $scope.artists.length-1) {
$scope.nextItem = Number($routeParams.itemId)+1;
} else {
$scope.nextItem = 0;
}
});
}]);
});
use data-main="path/file.js" to specify the file to load scripts..
<script data-main="path/file.js" src="js/require.js"></script>
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>App Demo</title>
<script data-main="js/main" src="js/require.js"></script>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="main" ng-view></div>
</body>
</html>
and in main.js
require.config({
baseUrl: "js",
paths: {
'angular': '.../lib/angular.min',
'angular-route': '.../lib/angular-route.min',
'angularAMD': '.../lib/angular-animate.min.js'
},
shim: { 'angular-animate.min': ['angular'], 'angular-route': ['angular'] },
deps: ['app']
});
require(['requireModule,'requireModule2'],function(requireModule,requireModule2){
//code to start the application
})
Your code doesn't allow to start the application through requirejs . You need to define AngularJS Components as RequireJS Modules
RequireJS loads all code relative to a baseUrl. The baseUrl is normally set to the same directory as the script used in a data-main attribute for the top level script to load for a page. The data-main attribute is a special attribute that require.js will check to start script loading. This example will end up with a baseUrl of scripts:
<!--This sets the baseUrl to the "scripts" directory, and
loads a script that will have a module ID of 'main'-->
<script data-main="scripts/main.js" src="scripts/require.js"/>
For more information on this, check Loading JS Files - Require.js
I am noob to angular and Cordova. I am developing a cordova application. I have the following code:
app.js:
var myApp = angular.module('myApp', ['ngSanitize', 'ngAnimate', 'ngRoute']).
config(function ($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: '/home.html',
controller: 'homeController'
})
.when('/login', {
templateUrl: '/login.html',
controller: 'loginController'
})
.when('/register', {
templateUrl: '/register.html',
controller: 'registerController'
})
.otherwise({
redirectTo: '/home.html'
})
})
.run(['$rootScope', '$location', 'authProvider', function ($rootScope, $location, authProvider) {
$rootScope.$on('$routeChangeStart', function (event) {
if (!authProvider.isLoggedIn()) {
alert('login');
$location.path('/login')
}
});
}]).
factory('authProvider', function () {
var user;
return {
setUser: function (aUser) {
alert('set user');
user = aUser;
},
isLoggedIn: function () {
alert('is loged in');
return (user) ? true : false;
}
};
});
And my index.js is as below:
var app = {
initialize: function () {
this.bindEvents();
},
bindEvents: function () {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function () {
app.receivedEvent('deviceready');
angular.bootstrap(document, ['myApp']);
},
receivedEvent: function (id) {
console.log('Received Event: ' + id);
}
};
app.initialize();
And my index.html is as below:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<!--Shared Scripts-->
<script type="text/javascript" src="js/shared/jquery.min.js"></script>
<script type="text/javascript" src="js/shared/angular.js"></script>
<script type="text/javascript" src="js/shared/angular-route.min.js"></script>
<script type="text/javascript" src="js/shared/angular-animate.min.js"></script>
<script type="text/javascript" src="js/shared/angular-sanitize.min.js"></script>
<!--Custom Scripts-->
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/homeController.js"></script>
<script type="text/javascript" src="js/loginController.js"></script>
<title></title>
</head>
<body>
<div ng-view></div>
<script type="text/javascript" src="cordova.js"></script>
</body>
</html>
When I emulate my app in browser(cordova emulate browser), every thing is OK and ng-view works nicely, but when I run it on android device(cordova run android), ng-view does not work!
I have also tried to add :
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
to my app.js, but no success! I have also tried to define my html and body as below:
<html ng-app='myApp'>
or
<body ng-app='myApp'>
But no success !
I am using AngularJs 1.5.8 and Cordova 6.2.0 and running my app on Android 4.0
Updated
After inspecting a Android 5.0 device, I found out that there is an error that saying:
Failed to load resource: net::ERR_FILE_NOT_FOUND file:///login.html
Error: [$compile:tpload] Failed to load template: /login.html (HTTP
status: -1 )
Would you please help me solve this problem?
Thank you
I finally find the solution.
Just moving my views(login.html and home.html) into a folder(for example views) and add dot before my UrlTemplate
$routeProvider
//define the routes and their corresponded controllers
.when('/home', {
templateUrl: './views/home.html',
controller: 'homeController'
})
.when('/login', {
templateUrl: './views/login.html',
controller: 'loginController'
})
.when('/register', {
templateUrl: './views/register.html',
controller: 'registerController'
})
.otherwise({
redirectTo: './views/home.html'
})
I have 2 html file and I want to pass parameters via angular service between them.
these are the files I have:
index.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl2">
</div>
enter here
<script>
var app=angular.module("myApp");
app.controller("myCtrl2", ['$scope','$location', 'myService',
function($scope, $location, myService) {
myService.set("world");
}]);
</script>
</body>
</html>
enter2.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl3">
hello {{x}}
</div><script type="text/javascript">
var app=angular.module("myApp");
app.controller("myCtrl3", ['$scope','$location', 'myService',
function($scope, $location, myService) {
$scope.x=myService.get();
}]);
</script>
</body>
</html>
services.js
var app=angular.module("myApp", []);
app.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
});
why can't I get "hello world" in enter2.html, but instead get "hello" (x is not found by service)...?
When you go from index.html to enter2.html the whole page loads from scratch. For the data that you are expecting to stay in the browser, you might need to use advanced angular concepts such as loading just a part of the page using ng-view.
If that's something you have already overruled, saving the data in the service somewhere (may be the browser session) before unloading (window.onunload event) the page and then loading it back from there when the service loads (window.onload event) could also work.
Here is a working example based on your code.
I kept your index.html and added ui-view to have a single page application. The app uses 'ui.router'.
In the myCtrl2 I saved the data in the service, and call it back from myCtrl3:
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
To keep things simple, I have one Javascript file:
angular.module('myApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'index.html',
controller: 'myCtrl2',
controllerAs: 'vm'
})
.state('enter2', {
url: '/enter2',
templateUrl: 'enter2.html',
controller: 'myCtrl3',
controllerAs: 'vm'
});
})
.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
})
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
I also uses the var vm=this and ControllerAs as often recommended to avoid $scope issues.
index.html looks like below... pleaes note the ui-sref instead of href:
<div ui-view="">
<a ui-sref="enter2">Enter here</a>
</div>
enter2.html is now just the div part and your content:
<div>
Hello {{ vm.x }}
</div>
Let us know if that helps.
Additional info:
AngularJS Routing Using UI-Router
AngularJS's Controller As and the vm Variable
Sounds like you need to use a controller for your view page
https://docs.angularjs.org/guide/controller
I am just setting up a simple Angular app as I've done countless times. I added a home state and a separate state for a note taking app, yet neither states are displaying/injecting the html partials into the ui-view. I think it might be an issue with my ui-router setup, but I cannot find the issue. I console log from my controllers and they trigger correctly, so the states are clearly pointing to the right controllers.
Index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
<script src="bower_components/angular/angular.js"></script>
<script src="node_modules/angular-ui-router/release/angular-ui-router.js"></script>
<script src="app.js"></script>
<script src="factory.js"></script>
<script src="config.js"></script>
</head>
<body ng-app="myApp">
<ui-view></ui-view>
</body>
</html>
config
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateURL: './home.html',
controller: 'homeCtrl'
})
.state('list', {
url: '/list',
templateURL: '/list.html',
controller: 'listCtrl'
})
$urlRouterProvider.otherwise('/home');
});
app.js
'use strict';
var app = angular.module('myApp', ['ui.router']);
app.controller('listCtrl', function($scope, myFactory) {
console.log("list working!");
$scope.items = myFactory.items
$scope.addItem = function() {
$scope.items.unshift($scope.newItem);
$scope.newItem = "";
}
})
app.controller('homeCtrl', function($scope) {
console.log("home working!");
$scope.test = 'test'
})
My home state should load a partial containing:
<div>
<h1>Welcome!</h1>
</div>
Plunker
http://plnkr.co/edit/ngHYDtx0VBe2YPlBeJ3t?p=preview
It has to be
templateUrl: './home.html',
Also, it is not desirable to use relative paths for templates, './home.html' and 'home.html' will be cached internally as two different templates.
I'm trying to figure out why my angular app isn't working.
so I have the following code:
app.modules.js
angular.module("quickscan", [
"ui.router",
"quickscan.controllers"
]);
angular.module("quickscan.controllers", []);
app.routes.js
var app = angular.module("quickscan");
app.config(function ($stateProvider, $urlRouterProvider, $controllerProvider, $compileProvider, $filterProvider, $provide, $httpProvider) {
$urlRouterProvider.otherwise("/test");
$stateProvider
.state("app", {
abstract: true,
templateUrl: "shared/Layout/Main.html"
})
.state("app.root", {
url: "/test",
templateUrl: "shared/Main/Main.html"
})
.state("buildings", {
url: "/buildings",
controller: "BuildingDetailController",
templateUrl: "components/BuildingDetail/BuildingDetailView.html"
});
});
index.html
<!DOCTYPE html>
<html>
<head>
<title>Quickscan App v2</title>
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=no">
<link rel="stylesheet" href="content/css/app.css">
</head>
<body>
<div ng-view id="view"></div>
<!-- order dependend scripts -->
<script src="scripts/jquery/jquery.js"></script>
<script src="scripts/angular/angular.js"></script>
<script src="app/app.module.js"></script>
<!--remaining scripts-->
<script src="content/js/scripts.js"></script>
<!--angular scripts-->
<script src="content/js/all.js"></script>
<script>
setTimeout(function() {
angular.bootstrap(document, ['quickscan']);
console.log("Hello");
}, 3000);
</script>
</body>
</html>
all.js
(function () {
var app = angular.module("quickscan");
app.config(function ($stateProvider, $urlRouterProvider, $controllerProvider, $compileProvider, $filterProvider, $provide, $httpProvider) {
$urlRouterProvider.otherwise("/test");
$stateProvider
.state("app", {
abstract: true,
templateUrl: "shared/Layout/Main.html"
})
.state("app.root", {
url: "/test",
templateUrl: "shared/Main/Main.html"
})
.state("buildings", {
url: "/buildings",
controller: "BuildingDetailController",
templateUrl: "components/BuildingDetail/BuildingDetailView.html"
});
});
})();
var Building = function (data) {
// some other class
return building;
};
var Category = function (data, parent, building) {
// some class
return category;
};
(function () {
"use strict";
angular
.module("quickscan.controllers")
.controller("BuildingDetailController",
function ($scope, $rootScope) {
var vm = this;
vm.title = "Building Detail";
function activate() {
console.log("test");
}
activate();
});
})();
(function () {
"use strict";
angular
.module("quickscan.controllers")
.controller("CategoryDetailController",
function ($scope, $rootScope) {
var vm = this;
vm.title = "Building Detail";
function activate() {
console.log("test");
}
activate();
});
})();
but the app isn't loading any of my views, my controllers arn't reporting test and it's not getting redirected to /# nor any errors are showing up, any one has a clue?
It looks like you are not using the ui-view directive, see https://github.com/angular-ui/ui-router/wiki/The-Components
Your
<div ng-view id="view"></div>
Should be
<div ui-view></div>