Error: [$injector:unpr] in angular.js - javascript

I have just started learning angularjs. I am trying the tutorial one given on their official website.
http://docs.angularjs.org/tutorial/step_08
What i am trying to achieve is to build multiple views by adding routing.
when i access home.html it is displaying all the mobile list perfectly but once i click on the link to get the details of any of the mobile the next page gives me this error
[$injector:unpr]
do notice there is no unknown provider error
and all the expression on phone-detail.html is being printed as it is not being evaluated.
here is my app.js code
var phonecatApp = angular.module('phonecatApp', [
'ngRoute',
'phonecatControllers'
]);
phonecatApp.config(['$routeProvider',function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: 'PhoneListCtrl'
}).
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: 'PhoneDetailCtrl'
}).
otherwise({
redirectTo: '/phones'
});
}]);
then my controller.js code is
var phonecatControllers = angular.module('phonecatControllers', []);
phonecatControllers.controller('PhoneListCtrl', ['$scope', '$http',function ($scope, $http) {
$http.get('phones/phones.json').success(function(data) {
alert(data);
$scope.phones = data;
});
$scope.orderProp = 'age';
}]);
phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams','$http',function($scope, $routeParams,$http) {
$http.get('phones/' + $routeParams.phoneId + '.json').success(function(data) {
$scope.phone = data;
});
}]);
home.html code
<html lang="en" ng-app="phonecatApp">
<head>
<title>Hello world example from angular js</title>
<link type="text/css" rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="css/custom.css"/>
<script type="text/javascript" src="scripts/angular.min.js"></script>
<script type="text/javascript" src="scripts/angular-route.min.js"></script>
<script type="text/javascript" src="scripts/app.js"></script>
<script type="text/javascript" src="scripts/controller.js"></script>
</head>
<body>
<div class="row">
<div class="container">
<div ng-view></div>
</div>
</div>
</body>
</html>
phone-list.html code -
<div class="col-lg-12">
<hr>
<p class="pull-right col-lg-4">
<input type="text" ng-model="query" class="form-control col-lg-6" placeholder="Search" style="width:auto;">
<select ng-model="orderProp" class="form-control col-lg-6" style="width:auto;">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
<option value="-age">Oldest</option>
</select>
</p>
<p class="col-lg-6">Total number of phones: {{phones.length}}</p>
<div class="clearfix"></div>
<hr>
<h3 ng-bind-template="Thumbnail view | Search for : {{query}}">List view</h3>
<div class="row">
<div class="col-lg-4" ng-repeat="phone in phones | filter:query | orderBy:orderProp">
<div class="thumbnail">
<a href="#/phones/{{phone.id}}">
<img src="{{phone.imageUrl}}" data-src="{{phone.imageUrl}}" alt="{{phone.name}}">
</a>
<div class="caption">
<h3>{{phone.name}}</h3>
<p>{{phone.snippet}}</p>
</div>
</div>
</div>
</div>
</div>
phone-detail.html code -
<div class="phone-images">
<img ng-src="{{img}}"
class="phone"
ng-repeat="img in phone.images"
ng-class="{active: mainImageUrl==img}">
</div>
<h1>{{phone.name}}</h1>
<p>{{phone.description}}</p>

I got it where was the problem.
It was because i copied content in phone-detail.html from github which should come in a later step. in phone-detail there was some code like
{{phone.hardware.accelerometer | checkmark}}
here checkmark is a filter but i didn't introduced filter at all.
So solution was I added filter.js with content
angular.module('phonecatFilters', []).filter('checkmark', function() {
return function(input) {
return input ? '\u2713' : '\u2718';
};
});
then import script.js in home.html and it worked fine.
So i did two mistake -
1. Introducing code for filters without registering any filter.
2. Didn't post the whole code for phone-detail.html so that you can figure out the mistake number one.
A special thanks to #Lorenzo to help me dig out the problem.

As you defined an App module with var phonecatApp = ... you have to use it to create your controllers for Angular to know that phonecatController "belongs to" phonecatApp.
So just replace angular.module with phonecatApp.controller
Replace this line
var phonecatControllers = angular.module('phonecatControllers', []);
//------------------------^-------------^---------------------------
With this
var phonecatControllers = phonecatApp.controller('phonecatControllers', []);
//------------------------^--------------------^---------------------------
Or you can do
angular.module('phonecatApp').controller('phonecatControllers', []);

Related

Getting started - Controller not a function got undefined

I am getting started with Angular routes. When I define the angular route for someNameController by putting its code into a controllers file and putting the html into a html file, the controller does not seem to bind well with the html. However, it is working correctly with my other controllers.
Links I have tried:
ngRoute not working. is there something i am doing wrong
angularjs ngRoute not working
https://docs.angularjs.org/error/ng/areq?p0=controllers%2FsomeNameController&p1=not%20a%20function,%20got%20undefined
index.html
<!DOCTYPE HTML>
<html>
<head>
<link href="bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="bower_components/angular/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.min.js"></script>
<script src="app.js"></script>
<script src="config.js"></script>
<script src="controllers/someNameController.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="jumbotron">
<div ng-app="someApp">
<div ng-view></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
someCustomersView.html
<div>
<h2>
Hello, world!
</h2>
<p>
{{ desc }}
</p>
<p>
<a class="btn btn-primary btn-large" href="#">Learn more</a>
</p>
<input type="text" class="form-control" ng-model="someName"/>
<br>
<p>{{ someName | uppercase }}</p>
<ul ng-repeat="customer in customers">
<li class="list-group-item">{{ customer | lowercase }}</li>
</ul>
</div>
someNameController.js
someApp.controller("someNameController", function($scope){
$scope.customers = ["Customer2", "Customer3", "Customer4", "Customer5"]
})
I made a mistake while declaring routes in config.js file.
I was assigning directory while assigning routes even after including the scripts for controllers in the html along with the directory. I was doing this in config.js:
someApp.config(["$routeProvider", function($routeProvider, $locationProvider){
$routeProvider.when("/showSomeButtonsGroup", {
templateUrl : "views/view3.html",
controller : "controllers/page67Controller"
})
.when("/", {
templateUrl : "views/someCustomersView.html",
controller : "someNameController"
})
}])
instead of doing like this:
someApp.config(["$routeProvider", function($routeProvider, $locationProvider){
$routeProvider.when("/showSomeButtonsGroup", {
templateUrl : "views/view3.html",
controller : "page67Controller"
})
.when("/", {
templateUrl : "views/someCustomersView.html",
controller : "someNameController"
})
}])

Routing ng-view with $location.path(..)

I'm trying to implement an answer on another StackOverflow question, using a link in the header to redirect Index.html's ng-view.
When loading pages directly via: http://server/#/page the app works without issue (no console errors, page renders correctly, angular/js logic runs correctly). My routing logic returns 'undefined' when I step through the logic (into the angular library), delivering me to http://server/# which is a great page of nothingness, except the header and footer render correctly.
I'm not sure what I'm doing incorrectly.
I'm going to be selective as to what I include code wise (just to keep this at a reasonable length) but if I left something important out, don't hesitate to request it.
Index.html:
<!DOCTYPE html>
<html ng-app="passwordResetApp">
<head>
<title>COP Azure B2B Password Reset</title>
<meta charset="utf-8"/>
<!--Lib-->
<!--ng base-->
<script src="app/lib.bower/angular/angular.js"></script>
<script src="app/lib.bower/angular-route/angular-route.js"></script>
<!--ui grid-->
<script src="app/lib.bower/angular-ui-grid/ui-grid.min.js"></script>
<link href="app/lib.bower/angular-ui-grid/ui-grid.min.css" rel="stylesheet"/>
<!--Misc-->
<link rel="stylesheet" href="app/lib.bower/bootstrap/dist/css/bootstrap.min.css" />
<!--Custom-->
<script src="app/app.js"></script>
<!--Custom - Services-->
<script src="app/services/resetRequestService.js"></script>
<script src="app/services/adValidationService.js"></script>
<!--Custom - Controllers-->
<script src="app/controllers/HeaderController.js"></script>
<script src="app/controllers/PasswordResetRequestController.js"></script>
<!--Custom modules-->
<script src="app/modules/header.js"></script>
<!--Custom - Other-->
<link rel="stylesheet" href="app/css/passwordReset.css"/>
</head>
<body ng-app>
<div class="container">
<!--<div ng-include="'app/views/_header.html'"></div>-->
<div header></div>
<div class="viewWrapper">
<div ng-view></div>
</div>
<div class="push"></div>
</div>
<div ng-include="'app/views/_footer.html'"></div>
</body>
</html>
app.js:
(function() {
'use strict';
var app = angular.module('passwordResetApp', ['ngRoute']);
app
.config(
function($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'app/views/passwordReset.html',
controller: 'ResetRequestController as vm',
caseInsensitiveMatch: true
}).when('userSearch', {
templateUrl: 'app/views/userSearch.html',
controller: 'ResetRequestController as vm',
caseInsensitiveMatch: true
}).otherwise({ redirectTo: '/' });
}
);
app.directive('header',
function() {
return {
restrict: 'A',
//This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
replace: true,
templateUrl: 'app/views/_header.html',
controller: 'HeaderController as vm',
caseInsensitiveMatch: true
}
});
app.run([
'$route', '$http', '$rootScope',
function ($route, $http, $rootScope) {
$http.defaults.withCredentials = true;
$rootScope.getUrlPath = function (url) {
return baseUrl + url;
};
}
]);
}());
_header.html:
<header id="pageHeader">
<div class="row">
<div class="col-sm-4 col-md-3 col-lg-2 cop-logo-container">
<img id="cop-logo" src="app/img/ConocoPhillips_Logo.png" />
</div>
<div class="col-sm-4 col-md-6 col-lg-8">
<h2>Azure B2B Password Reset</h2>
{{vm.currentUser.name}}
</div>
<div class="col-sm-4 col-md-3 col-lg-2">
<div class="pull-right" style="padding: 20px">
<div ng-if="vm.currentUser" id="headerUser">
<p>Welcome, <span class="username">{{vm.currentUser.name}}</span></p>
</div>
<div ng-if="!vm.currentUser">
<div class="btn btn-primary">Login</div>
</div>
</div>
</div>
</div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<ul ng-if="vm.currentUser" class="nav navbar-nav">
<li>Home</li>
<li>Search Users</li>
<li>Logout</li>
</ul>
<ul ng-if="!vm.currentUser" class="nav navbar-nav">
<li>Home</li>
</ul>
</div>
</div>
</nav>
</header>
HeaderController.js:
(function() {
'use strict';
var app = angular.module('passwordResetApp');
var headerController = function ($scope, $location) {
var vm = this;
vm.currentUser = {};
vm.currentUser.name = 'caninc';
vm.changeView = function(view) {
$location.path(view);
}
};
app.controller('HeaderController', headerController);
}());
Issue is with <li>Home</li>
# so when clicked http://server/# not http://server/#/page

How to bind HTML component with ng-repeat based on a pre-defined condition

I am very new to AngularJS. I have made an html component which is to be reused across the whole app. Let's say this component gives out the basic info of a product. The basic structure of the HTML is as below:
<div class="visible-sm-block">
<div class="row">
<div class="col-sm-2">
<img class="img-circle img-responsive" alt="Image of product"
ng-src="{{}}"/>
</div>
<div class="col-sm-10">
<label>{{ProductName}}</label>
<p>{{CompanyName}}</p>
<p>{{ShippedTo}}</p>
</div>
</div>
</div>
The product.js file goes as:
(function() {
'use strict';
angular
.module('product')
.directive('productDetails', productDetails);
/** #ngInject */
function productDetails() {
var directive = {
restrict: 'E',
templateUrl: 'app/components/productDetails/productDetails.html'
};
return directive;
}
})();
The small HTML component would be reused across other HTML pages in the app like this:
<product-details></product-details>
Now the problem is I cannot bind data with the HTML component when it is used across my pages. The controller for those pages is in a separate folder: app/productshipping/productshipping.controller.js
I tried using ng-controller="controller_name" in the HTML component itself but no result came. :( Please help.
This is really an interesting question. The code is given below. I am developing an angular framework. So do let me know if you need any further assistance.
Product.js file as follows
"use strict";
angular.module("app",[]);
angular.module("app").controller("productController", ['$scope', function ($scope) {
}]);
angular.module("app").directive("tmHtml", function () {
return {
transclude: false,
scope: {
productName: '#',
companyName: '#',
shippedTo: '#'
},
controller: "productController",
templateUrl: "/templates/HideShow.html"
};
});
Template HTML file as follows
<html ng-app="app">
<head>
<title></title>
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
<script src="../Scripts/jquery-1.10.2.js"></script>
<script src="../Scripts/bootstrap.js"></script>
</head>
<body ng-controller="productController">
<div class="visible-sm-block">
<div class="row">
<div class="col-sm-2">
<img class="img-circle img-responsive" alt="Image of product" ng-src="{{}}" />
</div>
<div class="col-sm-10">
<label>{{productName}}</label>
<p>{{companyName}}</p>
<p>{{shippedTo}}</p>
</div>
</div>
</div>
</body>
</html>
How to reuse this as follows
<html ng-app="app">
<head>
<title></title>
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
<script src="../Scripts/jquery-1.10.2.js"></script>
<script src="../Scripts/bootstrap.js"></script>
<script src="../Scripts/angular.js"></script>
<script src="../js/Product.js"></script>
</head>
<body>
<div>
<tm-Html product-Name="Sankar" company-Name="Sankar" shipped-To="Sankar">
</tm-Html>
</div>
</body>
</html>

is difference between local install or reference url of angular js

I am trying to develop an application using angular js .it a simple routing .when i add the angular by url like this :
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="~/js/app.js"></script>
My application works fine ,but when i add like this :
<script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/angular-route.min.js"></script>
<script src="~/js/app.js"></script>
I got this error :
angular.js:68 Uncaught Error: [$injector:modulerr] Failed to instantiate module sampleApp due to:
Error: [$injector:unpr] Unknown provider: $routeProvide
Here is my app.js
//Define an angular module for our app
var sampleApp = angular.module('sampleApp', []);
//Define Routing for app
//Uri /AddNewOrder -> template add_order.html and Controller AddOrderController
//Uri /ShowOrders -> template show_orders.html and Controller AddOrderController
sampleApp.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/AddNewOrder', {
templateUrl: 'templates/add_order.html',
controller: 'AddOrderController'
}).
when('/ShowOrders', {
templateUrl: 'templates/show_orders.html',
controller: 'ShowOrdersController'
}).
otherwise({
redirectTo: '/AddNewOrder'
});
}]);
sampleApp.controller('AddOrderController', function ($scope) {
$scope.message = 'This is Add new order screen';
});
sampleApp.controller('ShowOrdersController', function ($scope) {
$scope.message = 'This is Show orders screen';
});
Here is my html code :
<!DOCTYPE html>
<html lang="en">
<head>
<title>AngularJS Routing example</title>
</head>
<body ng-app="sampleApp">
<div class="container">
<div class="row">
<div class="col-md-3">
<ul class="nav">
<li> Add New Order </li>
<li> Show Order </li>
</ul>
</div>
<div class="col-md-9">
<div ng-view></div>
</div>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="~/js/app.js"></script>
</body>
</html>
You will need to add the reference to the module (angular route module) that your module is dependent on. The error says that $routeProvide is unknown to it and that is available in the angular route module.
//Define an angular module for our app
var sampleApp = angular.module('sampleApp', ['ngRoute']);

Angularjs: Unable to run the code

I am new to angularjs and these are the files I have created.
I have tried my best but could not run the above code.
myApp(Folder)
- app.js
- controller.js
- index.html
- phone-detail.html
- phone-list.html
The Home page is the phone-list.html and when clicked on a phone routes to a phone-detail.html page.
app.js
var phonecatApp = angular.module('phonecatApp', ['ngMaterial','phonecatControllers','$routeProvider']);
phonecatApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'phone-list.html',
controller: 'PhoneListCtrl'
}).
when('/phones/:phoneId', {
templateUrl: 'phone-detail.html',
controller: 'PhoneDetailCtrl'
}).
otherwise({
redirectTo: '/phones'
});
}]);
controller.js
var phonecatControllers = angular.module('phonecatControllers', []);
phonecatControllers.controller('PhoneListCtrl', ['$scope',
function ($scope) {
$scope.phones =
[{"Device":"ipad mini","Model":"MD528LL/A"},
{"Device":"ipadair","Model":"MD785LL/A"}]
}]);
phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams',
function($scope, $routeParams) {
$scope.Model = $routeParams.Model;
}]);
index.html
<!doctype html>
<html lang="en" ng-app="phonecatApp">
<head>
<!-- Angular Material CSS now available via Google CDN; version 0.10 used here -->
<!-- Angular Material Dependencies -->
<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.2.1/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-resource.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.10.0/angular-material.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>
<script src="controller.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-view>
</div>
</body>
</html>
phone-list.html
<div class="mainContent" style="margin:5%">
<li ng-repeat="phone in phones" style="float:left; margin:40px" >
<md-content style="padding:0px; overflow-y: hidden">
<md-card style="width:300px; height:300px; margin:0px" >
<img ng-src="{{phone.image}}" class="md-card-image" style="height:40%" alt="image caption" >
<md-card-content style="padding:0; height:25%">
<h6 class="md-title">{{phone.Device}}</h6> <hr style="opacity:0.5">
</md-card-content>
<md-card-footer class="md-actions" layout="row" layout-align="center" style="padding:0">
<md-button class="md-raised">Action 1</md-button>
<md-button class="md-raised">Action 2</md-button>
</md-card-footer>
</md-card>
</md-content>
</li>
</div>
phone-detail.html
{{phone.Device}}
You should inject ngRoute module instead of $routeProvider in :
var phonecatApp = angular.module('phonecatApp', ['ngMaterial','phonecatControllers','$routeProvider'])
Also make sure you included the sources of angular-route.js as angular routing is separated from angular sources.
Edit: From the index.html you posted I see you included angular-route.js but it appears you are missing the script of angular-material, so be sure to add :
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.10.0/angular-material.min.js"></script>

Categories