How to use Multiple View with routing using angularjs - angularjs

I want to use multiple controller using routing concept of angularjsbut i am getting as below error.
Error:
Error: [$injector:unpr] http://errors.angularjs.org/1.2.25/$injector/unpr?p0=%24windowsProvider%20%3C-%20%24windows
at Error (native)
at http://localhost:2585/Scripts/angular.min.js:6:450
at http://localhost:2585/Scripts/angular.min.js:36:202
at Object.c [as get] (http://localhost:2585/Scripts/angular.min.js:34:305)
at http://localhost:2585/Scripts/angular.min.js:36:270
at c (http://localhost:2585/Scripts/angular.min.js:34:305)
at d (http://localhost:2585/Scripts/angular.min.js:35:6)
at Object.instantiate (http://localhost:2585/Scripts/angular.min.js:35:165)
at http://localhost:2585/Scripts/angular.min.js:67:419
at link (http://localhost:2585/Scripts/angular-route.js:910:26) <div data-ng-view="" class="ng-scope">
My try:
_Layout.cshtml
<html leng="en" data-ng-app="#ViewBag.InitModule">
index.cshtml
#{
ViewBag.Title = "Home Page";
ViewBag.InitModule = "homeIndex";
}
#section Scripts{
<script src="../Scripts/angular-route.js"></script>
<script src="~/js/home-index.js"></script>
}
<div data-ng-view=""></div>
home-Index.js
var module = angular.module("homeIndex", ['ngRoute'])
module.config(function ($routeProvider) {
$routeProvider.when("/", {
controller: "homeIndexController",
templateUrl: "/templates/AccountTypeView.html"
});
$routeProvider.when("/add", {
controller: "newAccountTypeController",
templateUrl: "/templates/addAccountType.html"
});
$routeProvider.otherwise({ redirectTo: "/" });
});
//homeIndexController
function homeIndexController($scope, $http) {
//homeIndexController code which is working fine
}
//newAccountTypeController
function newAccountTypeController($scope, $http, $windows) {
$scope.newAccountType = {};
$scope.save() = function () {
alert($scope.newAccountType.name);
};
}
addAccountType.html
<h3>Add New AccountType</h3>
<form name="AddAccountType" novalidate data-ng-submit="save()">
<div class="form-group">
<label for="title">AccountType</label>
<input type="text" class="form-control" data-ng-model="newAccountType.name" required />
<span class="has-error" data-ng-show="AddAccountType.name.$error.required">*</span>
</div>
<div>
<input type="submit" value="Submit" class="btn-primary" />
</div>
</form>
When I am calling homeIndexController controller then it is working fine but when i and trying to call newAccountTypeController then i am getting error as above.
As i know it is not big error but I am new with angularjs. to solve it i did lots of google and i got lots of answer also but unable to solve. So if someone have solution of this problem then help me any suggestion will be accepted. Thanks it advance.

The error is telling you that angular couldn't find the service you are injecting on your controller, named windowsProvider.
Maybe you meant $window?
function newAccountTypeController($scope, $http, $window) {
$scope.newAccountType = {};
$scope.save = function () {
alert($scope.newAccountType.name);
};
}
By the way, you had an error on your save function definition...
EDIT: 'unpr' stands for Unknown Provider. Yes I know, super verbose right ?

Related

Async variable stored in $rootScope not available in other controllers

I am using Angular 1.x for my stack and when I make an API call and store the response in the $rootScope, it is not accessible in other controllers' view.
My controller:
angularApp.controller('mainController', ['$scope', '$rootScope', '$http', function($scope, $rootScope, $http){
var checkIfAuthenticated = function(){
return $http.get('/api/isAuthenticated');
};
checkIfAuthenticated()
.then(function(res) {
if(res.status===200){
console.log("Success");
$rootScope.userLoggedIn = true;
}
})
}]);
Now, in another controller's view I use it like this:
<div ng-if="userLoggedIn" class="py-1 pl-1 pr-1">
<span><b>Message Board</b></span>
<div class="form-control" readonly id="lockTextbox">Show something</div>
</div>
The problem is, the API call /api/isAuthenticated does provide the right response (status 200) but the ng-view gets it wrong.
I am sure this is to do with $rootScope.userLoggedIn being a response from an async call (as I get Success in my console) but how do I solve it?
Thanks in advance!
EDIT
After I posted the question, I noticed that in the mainController's view, the ng-if logic doesn't work either. What is very strange is that when I open up the browser's debug console, it starts working! I think this is just an async issue but I don't know how to solve it. How do I tell the view that the variable is on it's way?
OK, to solve the timing issue, I'll rework the answer completely. This should be a - quick and dirty but - working example:
index.html
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="plunker" ng-cloak>
<div ng-controller="MainCtrl as $ctrl">
<h1>Hello {{$ctrl.name}}</h1>
<p>Start editing and see your changes reflected here!</p>
<div ng-if="$ctrl.name === 'Angular.js'"><b>Message Board</b</div>
</div>
</body>
</html>
script.js
import angular from 'angular';
angular.module('plunker', []).controller('MainCtrl', function($scope, $http) {
const self = this;
self.name = 'Plunker';
console.log('hello');
function checkIfAuthenticated(){
console.log('get');
return $http.get('https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js');
};
checkIfAuthenticated().then(function(res) {
if(res.status===200){
console.log('Success');
self.name = 'Angular.js'; // insert any logic here
} else {
console.log('Failed');
}
})
});
Console
hello
get
Success
Does it work for you?
Working Example
The below demo shows the $rootScope variable available in both controllers after being set from a promise delayed by two seconds.
angular.module("app",[])
.controller('mainController', function($scope, $rootScope, $timeout) {
var checkIfAuthenticated = function(){
return $timeout(function() {
return { status: 200 };
}, 2000);
};
checkIfAuthenticated()
.then(function(res) {
if(res.status===200){
console.log("Success");
$rootScope.userLoggedIn = true;
}
})
})
.controller('otherController', function($scope) {
console.log("other controller");
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<fieldset ng-controller="mainController">
MAIN Controller userLoggedIn={{userLoggedIn}}<br>
<div ng-if="userLoggedIn">
Message Board - Show something
</div>
</fieldset>
<fieldset ng-controller="otherController">
OTHER Controller userLoggedIn={{userLoggedIn}}
<div ng-if="userLoggedIn">
Message Board - Show something
</div>
</fieldset>
</body>
I found the problem. I updated my Angular from 1.6.4 to 1.7.9 (and all modules like angular-sanitize etc) and that did the trick. Should have been the first thing I did but I missed it entirely

$scope not getting any values

So this is how my index.html is structured.
<html ng-app='information'>
<body ng-controller="FirstController as first>
<div ng-controller="SecondController as second>
<div id="information">
<myOwnDirective ng-controller="ThirdController as thirdCtrl"></myOwnDirective>
</div>
This is my custom directive.
(function() {
var app = angular.module('information', ['ui.bootstrap']);
app.directive('myOwnDirective', function(){
return {
restrict: 'E',
templateUrl: 'my-own-directive.html',
};
});
This is a custom directive template. my-own-directive.html
<uib-accordion tag ng-repeat="info in first">
<form ng-submit="thirdCtrl.updateInformation()">
<div class="form-group">
<label for="someprop">Property</label> <input type="text" name="someprop"
class="form-control" ng-model="info.propValue"
ng-readonly="info.propValue">
</div>
<button type="submit" class="btn btn-success btn-lg btn-block">Click</button>
</form>
This is my script file: myScript.js
(function() {
angular.module('information').controller('ThirdController', [ '$scope', function($scope) {
console.log("In third controller"); // This prints
this.updateInformation = function() {
console.log("Inside updateInformation");
console.log("Inside scope is: "+ $scope) // It is undefined
};
}]);
})();
What I want to get is get value of info.propValue from the scope but I cant seem to get it. It always shows up as undefined. I have a very long form whose contents I want to read but I cant seem to get the values. Once I have them I will bemaking an Ajax call using $http. Also, if I try to invoke function updateInformation() by doing $scope.updateInformation(), it doesnt invoke, but it does get called if I do this.updateInformation(). Why ?? What am I missing or what am I doing wrong? Any help is appreciated. Have been stuck on it for quite a while. Thank you.

Controller loaded by ng-include not working

I have a page with a pop-up I use on several pages and I load it using ng-include. In this pop-up there is three tabs also dynamically loaded using ng-include.
So my code looks like this:
<div ng-include="'/pages/ng-templates/Cockpit.html'"></div>
in Cockpit.html I have the following code:
<div id="dlgCockpit" class="Cockpit jquerydialog">
<div id="tabs">
<ul>
<li>tabA</li>
<li>tabB</li>
<li>tabC</li>
</ul>
<div id="tabA">
<div ng-include="'/pages/ng-templates/Cockpit-A.html'"></div>
</div>
<div id="tabB">
<div ng-include="'/pages/ng-templates/Cockpit-B.html'"></div>
</div>
<div id="tabC">
<div ng-include="'/pages/ng-templates/Cockpit-C.html'"></div>
</div>
</div>
</div>
<script src="/pages/ng-templates/scripts/Cockpit.js"></script>
In Cockpit-A.html I have the following Code:
<div id="dlgCockpitA">
<form name="frmA" class="cntrCockpitA form" ng-controller="AController">
<!-- some inputs using ng-model -->
</form>
</div>
<script src="/pages/ng-templates/scripts/Cockpit-A.js"></script>
Cockpit.js:
function showCockpit(vsTnID, vsBenutzer) {
$('#dlgCockpit').data('tnid', vsTnID);
var $dialog = $("#dlgCockpit")
.dialog({
autoOpen: false,
title: locBenutzer + ': ' + vsBenutzer + ' (ID: ' + vsTnID + ')',
width: 1000,
show: 'fade',
resizable: false,
open: function (event, ui) {
$("#tabs").tabs({ active: 0 });
angular.element($('.cntrCockpitA')).scope().showStammdaten(vsTnID, 'Standard');
},
close: function (event, ui) {
}
});
$dialog.dialog('open');
return false;
}
Cockpit-A.js:
app.controller('AController', ['$scope', '$http', function ($scope, $http) {
//some function definitions on $scope
}]);
When I load the page I get the following in the javascript console:
Error: [ng:areq] Argument 'AController' is not a function, got undefined
http://errors.angularjs.org/1.2.26/ng/areq?p0=StammdatenController&p1=not%20aNaNunction%2C%20got%20undefined
at http://localhost:63323/scripts/angular/angular-1.2.26.js:78:12
at assertArg (http://localhost:63323/scripts/angular/angular-1.2.26.js:1509:11)
at assertArgFn (http://localhost:63323/scripts/angular/angular-1.2.26.js:1519:3)
at http://localhost:63323/scripts/angular/angular-1.2.26.js:7278:9
at http://localhost:63323/scripts/angular/angular-1.2.26.js:6670:34
at forEach (http://localhost:63323/scripts/angular/angular-1.2.26.js:332:20)
at nodeLinkFn (http://localhost:63323/scripts/angular/angular-1.2.26.js:6657:11)
at compositeLinkFn (http://localhost:63323/scripts/angular/angular-1.2.26.js:6105:13)
at compositeLinkFn (http://localhost:63323/scripts/angular/angular-1.2.26.js:6108:13)
at publicLinkFn (http://localhost:63323/scripts/angular/angular-1.2.26.js:6001:30)
When calling showCockpit I get the following error in the line angular.element($('.cntrCockpitA')).scope().showStammdaten(vsTnID, 'Standard');:
Uncaught TypeError: undefined is not a function
Actually everything works if I put the script tag for Cockpit-A.js in the "base page" which is including Cockpit.html or if I create the Controller just by calling function AController($scope, $http) { ... }, but both of those are not an option.
I had the exact same problem. Found a solution thanks to: http://ify.io/lazy-loading-in-angularjs/
Basically, it is not possible to use app.controller(...) after bootstrapping the app. I suggest reading the link for more information. The solution is to save the controllerProvider ahead and use it to register the module.
var app = angular.module('myModule', []);
app.config(function($controllerProvider) {
app.controllerProvider = $controllerProvider;
});
// Later on... after bootstrapping...
app.controllerProvider.register('myController', function() {... });

Why isn't the Angular ng-click event firing?

I've been following a course to learn angularjs and I can't seem to get a simple ng-click binding to work.
HTML:
<body ng-controller="MainController">
<div ng-app="githubViewer">
<h1>{{message}}</h1>
<div>{{ error }}</div>
{{username}}
<form name="searchUser">
<input type="search" placeholder="Username to find" ng-model="username" />
<input type="submit" value="Search" ng-click="search(username)" />
</form>
<div>
<div>{{user.name}}</div>
<img ng-src="http://www.gravatar.com/avatar/{{user.gravatar_id}}" title="{{user.name}}">
{{user.gravatar_id}}
</div>
</div>
</body>
Javascript:
(function () {
var module = angular.module("githubViewer", []);
var MainController = function ($scope, $http) {
var onUserComplete = function (response) {
$scope.user = response.data;
};
var onError = function (reason) {
$scope.error = "Could not fetch the user";
$scope.reason = reason;
};
$scope.username = "angular";
$scope.message = "Github Viewer";
$scope.search = function (username) {
$http.get("https://api.github.com/users/" + username)
.then(onUserComplete, onError);
};
};
module.controller("MainController", MainController);
}());
When you click the search button (search for username "odetocode" or "robconery") it is supposed to display an image but the click event does not seem to be firing. I have searched the documentation and looked over the course again but I can't see what I'm doing wrong.
I'm currently using version 1.2.16 of angularjs.
You have the ng-controller declaration outside of the ng-app declaration right now:
<body ng-controller="MainController">
<div ng-app="githubViewer">
It should be the other way around, or have both on the same element
<body ng-app="githubViewer" ng-controller="MainController">
<div>
AngularJS evaluates your code, and checks for any directives you have declared from the ng-app element down, including the element it is declared on; This currently is missing the ng-controller directive, as it is placed on a parent element of the ng-app element.
You need to put the controller within the context of the module to have it within its scope.
Like so
<body ng-app="githubViewer" ng-controller="MainController">
Demo here

Very simple ng-model watch not working

Here is the jsfiddle.
http://jsfiddle.net/CLcfC/
code
var app = angular.module('app',['']);
app.controller('TestCtrl',function($scope){
$scope.text = 'Change Me';
$scope.$watch('text',function(){
alert('Changed !');
});
})
HTML
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="TestCtrl">
<input type="text" ng-model='text'/>
<span>{{text}}</span>
</div>
</div>
I am not able to see the change in $scope.text. Please help.
This is so easy but what am I missing?
Change the module creation to this, make sure you don't put a empty string in the []. (Obvious the empty string is not a module that can be injected.)
var app = angular.module('app', []);
Demo: http://jsfiddle.net/MWa66/
Your JavaScript file loads after the AngularJS initialization and that's why it fails to find your module. In order to fix it change the initialization to a manual initialization.
First change your HTML and remove the ng-app directive:
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div id="appRoot">
<div ng-controller="TestCtrl">
<input type="text" ng-model='text'/>
<span>{{text}}</span>
</div>
</div>
Then go to your JavaScript and use angular.bootstrap method to manually attach your module:
var app = angular.module('app',[]);
app.controller('TestCtrl',function($scope){
$scope.text = 'Change Me';
$scope.$watch('text',function(){
alert('Changed !');
});
});
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('appRoot'), ['app']);
});
You can find more help on manual AngularJS initialization here.
Thank you! I solved this annoying thing!
The solution that worked for me was that I use angular UI router and there I had used the following code
.state('app.monimes', {
url: "/monimes",
views: {
'menuContent' :{
templateUrl: "templates/monimes.html",
controller: 'sampleCtrl'
}
}
})
so then in the controller I had
/***
*
*Controller for tests..
*/
.controller('sampleCtrl',['$scope','sampleService', function($scope, $sampleService) {
$scope.username="em";
// Watch for changes on the username property.
// If there is a change, run the function
$scope.$watch('username', function(newUsername) {
// uses the $http service to call the GitHub API
// //log it
$scope.log(newUsername);
// and returns the resulting promise
$sampleService.events(newUsername)
.success(function(data, status, headers) {
// the success function wraps the response in data
// so we need to call data.data to fetch the raw data
$scope.events = data.data;
});
},true);
}
]);
and in the view I had
<div>
<label for="username">Type in a GitHub username</label>
<input type="text" ng-model="username" placeholder="Enter a GitHub username, like a user" />
<pre ng-show="username">{{ events }}</pre>
</div>
but that didn't work.
so I added ng-controller="sampleCtrl"
to the div and now it works :D
so that means that the view is loaded after the controller loads and the watcher doesn't get added to the watching variable.

Resources