Controller loaded by ng-include not working - angularjs

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() {... });

Related

Unable to get content AngularJs dynamic popover inside ngrepeat

I need to display a small popover which should open on click and goaway on clicking anywhere on the page.
I found a plunker (http://plnkr.co/edit/K7cYQSDEBS3cHvDfJNLI?p=preview) which matches this requirement however, unable to get it to work inside ng-repeat.
I saw several answers and Plunker examples but not able to get this to work.
Here is my html
<div ng-controller="TestController">
<div class="row" style="background-color: #ebebeb !Important; ">
<div style="text-align:center">
<table style="width:100% !important;">
<tr ng-repeat="member in TeamMembers" style="font-size:18px !important; height: 108px;">
<td style="display:block;margin-top:30px;text-align:left;"> {{member.FirstName}} {{member.LastName}} <i class="fa fa-info-circle" aria-hidden="true" ng-show="member.Description != null" popover-template="dynamicPopover.templateUrl" popover-placement="bottom" popover-elem descr="{{member.Description}}"></i></td>
</tr>
</table>
</div>
</div>
...
<script type="text/ng-template" id="descriptionModal.html">
<div class="adp-info-dialog">
<div class="modal-body">
<div class="row">
<div class="col-md-8 col-md-offset-1">
<div class="form-group">
<label class="fieldset-label">Test {{ dynamicPopover.descr }}</label>
</div>
</div>
</div>
</div>
</div>
</script>
Here is the JS
testApp.controller('TestController', function ($scope, $rootScope, $log, $modal, SiebelAccountTeamService, $filter, $element) {
$scope.dynamicPopover = {
templateUrl: 'descriptionModal.html',
descr: null
};
var result = TestService.GetTeamMembers();
result.then(function (data) {
$scope.TeamMembers = data.data;
}, function (e) {
console.log(e);
}).finally(function () {
$scope.CompleteLoading();
});
});
testApp.directive('popoverClose', function ($timeout) {
return {
scope: {
excludeClass: '#'
},
link: function (scope, element, attrs) {
var trigger = document.getElementsByClassName('trigger');
function closeTrigger(i) {
$timeout(function () {
angular.element(trigger[0]).triggerHandler('click').removeClass('trigger');
});
}
element.on('click', function (event) {
var etarget = angular.element(event.target);
var tlength = trigger.length;
if (!etarget.hasClass('trigger') && !etarget.hasClass(scope.excludeClass)) {
for (var i = 0; i < tlength; i++) {
closeTrigger(i)
}
}
});
}
};
});
testApp.directive('popoverElem', function () {
return {
scope: {
descr: '#'
},
link: function (scope, element, attrs) {
$scope.dynamicPopover.descr = scope.descr,
alert($scope.dynamicPopover.descr),
element.on('click', function () {
element.addClass('trigger');
});
}
};
});
Appreciate your help.
Update:
To show the data of the ng-repeat inside the popover content, we need to access the individual objects through the $index of the ng-repeat. Refer the below example.
Plunkr Demo
The problem here is that you are using ng-repeat which creates a new scope read more here.
Since replicating the issue with your code is tedious, I tried replicating the issue with the plunkr!
Solution:
Plunkr Demo
You can simply define a new controller inside the descriptionModal.html like so
HTML:
<script type="text/ng-template" id="myPopoverTemplate.html">
<div class="adp-info-dialog" ng-controller="tester">
<div class="modal-body">
<div class="row">
<div class="col-md-8 col-md-offset-1">
<div class="form-group">
<label class="fieldset-label">Test {{ $parent.$parent.dynamicPopover.content }}</label>
</div>
</div>
</div>
</div>
</div>
</script>
JS:
app.controller('tester', function ($rootScope, $scope) {
console.log($scope.$parent.$parent.dynamicPopover.title);
});
Then, we will be able to access the parent scope, using $parent, the html inside the above script uses the $parent to get the variable!
Please note: It took me two $parent to reach the required $scope to access the scope variable. In your scenario it will also require two, the way to check how many is needed is use console.log($scope), then open the console(F12), then traverse through the objects $parent property till you find the correct $scope. Then count the number of $parent traversed, that will be your required number of $parent to traverse!
P.S:
There is another method you can do this, since this method will require a significant rewrite of your code, I will provide the GIST, you can use the controller as syntax and access the correct scope.
Here is the SO Answer giving the method to do it
SO Answer
I hope this fixes you issue.

Angular ng-if throwing TypeError: Cannot read property '0' of null

I am trying to show and hide html using ng-if . When the $scope.isTokenValid is false, it works fine.But when $scope.isTokenValid is true I am getting below error. Please help
TypeError: Cannot read property '0' of null
at $parseFunctionCall (angular.js:12346)
at Object.expressionInputWatch (angular.js:12754)
at Scope.$get.Scope.$digest (angular.js:14235)
at Scope.$get.Scope.$apply (angular.js:14506)
at done (angular.js:9659)
at completeRequest (angular.js:9849)
at XMLHttpRequest.requestLoaded (angular.js:9790)
Controller
angular.module('clientApp')
.controller('RegCtrl', function($scope, $routeParams, $http) {
var url = "http://localhost:3000/signup/" + $routeParams.invitation_token;
$http.get(url)
.success(function(response) {
$scope.isTokenValid = response.isValid;
})
});
View
<div class="row" ng-if="isTokenValid()">
<h1>Valid</h1>
</div>
<div class="row" ng-if="!isTokenValid()">
<h1>InValid</h1>
</div>
You're using isTokenValid like a function when it is in fact a property, change it to:
<div class="row" ng-if="isTokenValid">
<h1>Valid</h1>
</div>
<div class="row" ng-if="!isTokenValid">
<h1>InValid</h1>
</div>

How to use Multiple View with routing using 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 ?

Data-binding arguments of a function with AngularJS in ng-click

I am using ng-click to call a function with arguments I get from the $scope. Unfortunately either are the arguments not processed from angular or I get this error:
Error: [$parse:syntax] Syntax Error: Token ':' not a primary expression at column 1 of the expression [:notification] starting at [:notification].
HTML snippet that results in error:
<div ng-click="goToNotif({{notification.id}})"></div>
HTML snippet not being processed from angular:
<div ng-click="goToNotif(notification.id)"></div>
IMPORTANT: notification is parsed from a repeat
<div(ng-repeat="notification in notifications")></div>
Here is the code for index.html, define "notifications" seperately -
<div ng-app="MyApp">
<div ng-controller="MainCtrl">
<div(ng-repeat="notification in notifications")>
<div ng-click="go(notification.id)"></div>
</div>
</div>
</div>
In main.js -
var app = angular.module('MyApp', []);
app.controller('MainCtrl', function($scope) {
$scope.go = function() {
//write code here.
}
});

why my routeprovider not working?

I am learning routing with angular java script ,
this is my index.html
<html lang="en" ng-app="eventsApp">
.....
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
<li>Create Event</li>
</ul>
</div>
</div>
<ng-view></ng-view>
</div>
This is my app.js,
var eventsApp = angular.module('eventsApp', ['eventsApp', 'ngRoute'])
eventsApp.config(function($routeProvider) {
$routeProvider.when('/newEvent',
{
templateUrl:'templates/NewEvent.html',
controller: 'EditEventController'
}).....
When i click on the button it do nothing and also doesn't load new event .
and get this error
"Error: [$injector:modulerr] Failed to instantiate module eventsApp due to:"
here is the controller
'use strict';
eventsApp.controller('EditEventController',
function EditEventController($scope, eventData) {
$scope.event = {};
$scope.saveEvent = function (event, form) {
if(form.$valid) {
eventData.save(event);
}
};
$scope.cancelEdit = function () {
window.location = "/EventDetails.html";
};
}
);
One of the things I'm noticing looks wrong is that you're passing in eventsApp as a dependency of itself.
var eventsApp = angular.module('eventsApp', ['eventsApp', 'ngRoute'])
Should be:
var eventsApp = angular.module('eventsApp', ['ngRoute'])
Secondly, you may want to check that you've included ngRoute into the page:
See installation instructions here: http://docs.angularjs.org/api/ngRoute
Check out a working example on Plunkr:
http://plnkr.co/edit/VZgTnBvi0Q8qtcpOUTx0

Resources