angular.js throws Cannot read property 'then' of undefined - javascript

I didn't updated any of my .js files, yet my nested views are not displaying at all (even though they were before) and throw this error in console.
Why is it throwing the error and not displaying my nested views as it was originally?
angular version: 1.6.0-rc.0 (.min.js)
angular-ui-router version: v0.3.1 (.min.js)
app.js
'use strict';
var app = angular.module('app', ['ui.router','controllers','filters']);
app.config(function($stateProvider, $urlRouterProvider)
{
$urlRouterProvider.otherwise('/');
// Initialize states
var homeState =
{
name:'home',
url:'/',
views:
{
'' : {templateUrl: 'partials/home.html'}, // App template that organizes the layout of the panels
'panel#home' : {templateUrl: 'partials/panel.html'} // Reusable panel template for multiple panels within app
}
};
// Register states
$stateProvider.state(homeState);
});
controller.js
'use strict';
var controllers = angular.module("controllers", []);
// Initialize controllers
controllers.controller('panelEvaluateController',function($scope)
{
$scope.header = 'Solve an Equation';
$scope.button = '<button>Solve</button>';
$scope.body = 'partials/panels/evaluate.html';
$scope.tooltip = 'Help';
});
controllers.controller('panelConvertController',function($scope)
{
$scope.header = 'Convert an Integer';
$scope.button = '<button>Convert</button>';
$scope.body = 'partials/panels/convert.html';
$scope.tooltip = 'Help convert';
$scope.bases =
[
{ value : 2 , name : 'Binary'},
{ value : 8 , name : 'Octal'},
{ value : 10 , name : 'Decimal'},
{ value : 16 , name : 'Hex'}
];
$scope.base =
[
{selected : 2},
{selected : 10}
];
});
controllers.controller('panelSolutionController',function($scope)
{
$scope.header = 'Solution';
$scope.button = '<div class="row"><div class="col-sm-6"><button><span class="glyphicon glyphicon-chevron-left"></span></button></div><div class="col-sm-6"><button><span class="glyphicon glyphicon-chevron-right"></span></button></div></div>';
$scope.body = 'templates/panels/solution.html';
$scope.tooltip = 'solve';
});
index.html
<!DOCTYPE html>
<html data-ng-app="app" lang="en">
<head>
<meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1">
<title>Show Your Work</title>
<link rel="stylesheet" href="vendor/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="resources/css/specific.css">
</head>
<body>
<div id="header">
<div class="header-color-line"></div>
<div id="logo">Show Your Work</div>
</div>
<div class="row" id="view-container">
<div data-ui-view=""></div> <!-- displays home.html -->
</div>
<script type="text/javascript" src="vendor/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="vendor/angular/angular.js"></script>
<script type="text/javascript" src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
<script type="text/javascript" src="vendor/bootstrap/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="resources/js/app.js"></script>
<script type="text/javascript" src="resources/js/controllers.js"></script>
<script type="text/javascript" src="resources/js/filters.js"></script>
</body>
</html>
filters.js
'use strict';
var filters = angular.module("filters", []);
filters.filter('trusted', function($sce)
{
return function(val)
{
return $sce.trustAsHtml(val);
};
});

You need to update the ui-router version which should match with the angular version, Now the versions you have mentioned does not match.
<script type="text/javascript" src="vendor/angular/angular.js"></script>
<script type="text/javascript" src="vendor/angular-ui-router/release/angular-ui-router.js"></script>

Related

How to use modal in angularjs ui?

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.

How can I make NgJsTree apply model updates?

In my project I have included: JQuery, JSTree, Angular and NgJsTree. Whenever I update my treeData model, the data change is not reflected in the tree.
tcwsApp.service('explorerService', ['$http', '$log', '$timeout',
function($http, $log, $timeout) {
var service = this;
service.treeData = {
rootNodes: [{
"text": "Initial node"
}]
};
return ({
getTreeData: getTreeData,
initService: initService
});
function initService() {
getRootNodes();
}
function getTreeData() {
return service.treeData;
}
function getRootNodes() {
var request = $http.get("api/explorer");
request.then(function(response) {
$log.debug(response);
service.treeData.rootNodes = response.data.list;
}, function(response) {
$log.error(response);
});
}
}
]);
tcwsApp.controller('explorerController', ['$log', 'explorerService',
function($log, explorerService) {
var explorer = this;
explorerService.initService();
explorer.treeData = explorerService.getTreeData();
explorer.applyChanges = function() {
return true;
};
explorer.treeConfig = {
core: {
multiple: false,
animation: true,
error: function(error) {
$log.error('treeCtrl: error from js tree - ' + angular.toJson(error));
},
check_callback: true,
worker: true
},
version: 1,
plugins: ['types', 'checkbox']
};
}
]);
tcwsApp.directive('explorerTree', function() {
return {
templateUrl: 'app/template/explorer_tree.html'
};
});
<!DOCTYPE HTML>
<html ng-app="tcwsApp">
<head>
<meta charset="utf-8">
<title>TCWS</title>
<link rel="stylesheet" href="lib/jstree/themes/default/style.min.css" />
<link rel="stylesheet" href="lib/lht-bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="lib/lht-bootstrap/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="app/tcws_app.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="lib/angular-messages.js"></script>
<script src="lib/jstree/jstree.js"></script>
<script src="lib/jstree/ngJsTree.js"></script>
<script src="lib/lht-bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<tcws-app>
<!-- directive contents pasted -->
<explorer-tree>
<div class="col-md-4" ng-controller="explorerController as explorer">
<div js-tree="explorer.treeConfig" ng-model="explorer.treeData.rootNodes" should-apply="explorer.applyChanges()" tree-events="ready:readyCB;create_node:createNodeCB" tree="explorer.treeInstance">
{{explorer.treeData.rootNodes}}
</div>
</explorer-tree>
</tcws-app>
<script src="app/tcws_app.js"></script>
<script src="app/controller/explorer_tree.js"></script>
</body>
</html>
This displays the initial node - however the debug output via {{explorer.treeData.rootNodes}} is updated correctly after the http.get request finishes.
Resulting web page
Jstree has 2 json formats:
default: node w/ children
alternative: node w/ parent
Automatic updates on model change are only possible with the alternative format as stated here: Github Issue.

Donut chart is not working in angularjs

I am new to AngularJS. I want to create a donut which has onclick function and it goes to next page. I am trying to create a donut but it shows empty page. also console shows no error. I referred this to create a donut here is my code. i tried to merge the working code.
<!doctype html>
<html ng-app="MyApp" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,300,500,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
</head>
<body ng-controller="MyCtrl">
<div ng-app="my.app"
donut-chart
donut-data='[
{label: "Download Sales", value: 12},
{label: "In-Store Sales",value: 30},
{label: "Mail-Order Sales", value: 20}
]'
donut-colors='["#31C0BE","#c7254e","#98a0d3"]'
donut-formatter='"currency"'>
</div>
<script>document.write("<base href=\"" + document.location + "\" />");</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-morris-chart/1.2.0/angular-morris-chart.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular-animate.js"></script>
<script src="app.js"></script>
</body>
</html>
and my js file
var app = angular.module("MyApp", ["ngAnimate"]);
app.controller('MyCtrl', function($scope, $timeout) {
$scope.name = '';
$scope.data = {
singleSelect: null,
multipleSelect: [],
option1: 'option-1',
};
$scope.forceUnknownOption = function() {
$scope.data.singleSelect = 'nonsense';
};
});
angular.module('my.app', [
'angular.morris-chart'
])
Try to change the app.js file to
angular.module('my.app', ['angular.morris-chart'])
.controller('MyCtrl', function($scope, $timeout) {
$scope.name = '';
$scope.data = {
singleSelect: null,
multipleSelect: [],
option1: 'option-1',
};
$scope.forceUnknownOption = function() {
$scope.data.singleSelect = 'nonsense';
};
});
The controller MyCtrl must be a controller of the app my.app.
See http://plnkr.co/edit/AsxnDG?p=preview
Alternatively, you can split up the app definition and the controller definition into two files. Usually, a file app.js is used for the definition of my.app and a file controllers.js is used for the controller definitions.
E.g.:
app.js
var mod = angular.module('my.app', ['angular.morris-chart']);
controllers.js
var mod = angular.module('my.app.controllers', []);
var MyCtrl = function($scope, $timeout) {
...
};
mod.controller('MyCtrl', ['$scope', '$timeout', MyCtrl]);

Jasmine test for Angular can't find my controller

I'm having trouble setting up Jasmine tests for an Angular app. Jasmine can't find my controller (I suspect it can't find my app at all).
Here is a sample that demonstrates the problem I'm running into:
angular.module('testMod', [])
.controller('testController', ['$scope', function($scope) {
$scope.person = {name: 'Jim', age: 14};
function innerFunction() {}
}]);
Test:
describe('testMod suite', function() {
var $rootScope, myController;
beforeEach( inject(function($injector) {
angular.module('testMod');
$rootScope = $injector.get('$rootScope');
var $controller = $injector.get('$controller');
myController = $controller('testController', {$scope: $rootScope});
}) );
it('works', function() {
expect( typeof myController.innerFunction).toBe('function');
});
});
It fails on the line
myController = $controller('testController', {$scope: $rootScope});
The error I'm seeing is:
Error: [ng:areq] Argument 'testController' is not a function, got undefined
I'm using the standalone SpecRunner.html for Jasmine, with my app and spec loaded:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Spec Runner v2.0.0</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css">
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>
<!-- angular-mock must be loaded AFTER Jasmine -->
<script type="text/javascript" src="../src/angular-1.2.5.min.js"></script>
<script type="text/javascript" src="../src/angular-mock-1.2.5.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../src/testMod.js"></script>
<!-- include spec files here... -->
<script type="text/javascript" src="spec/testMod.Test.js"></script>
</head>
<body>
</body>
</html>
Any suggestions are appreciated - I've been struggling with this for a while now.
There are several problems with your test:
You are not injecting scope properly.
You are not using scope properly.
There is a toBeDefined() method to check if function is defined no need to type check.
Change the code in your test to
describe('testMod suite', function() {
var $rootScope, testController;
beforeEach(module('testMod'));
beforeEach(inject(function($controller, $rootScope) {
myScope = $rootScope.$new();
ctrl = $controller('testController', {
$scope: myScope
});
}));
it('works', function() {
expect( myScope.innerFunction).toBeDefined();
});
});
Also, change your angular controller code to:
angular.module('testMod', [])
.controller('testController', ['$scope', function($scope) {
$scope.person = {name: 'Jim', age: 14};
$scope.innerFunction = function() {}
}]);

Angularjs app not working after adding new controller

Initially my controller.js looked like this
function MyCtrl1() {}
MyCtrl1.$inject = [];
function MyCtrl2() {
}
MyCtrl2.$inject = [];
And the html code like this
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>My AngularJS App</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script src="http://angular-ui.github.com/bootstrap/ui-bootstrap-tpls-0.2.0.js"></script>
<link rel="stylesheet" href="css/app.css"/>
</head>
<body>
<ul class="menu">
<li>view1</li>
<li>view2</li>
</ul>
<div ng-view></div>
<div>Angular seed app: v <span app-version></span></div>
<div>Author is : <span app-author></span></div>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
</body>
</html>
Here is the service.js code
angular.module('myApp.services', []).
value('version', '0.1')
.value('author','Jay');
And the directive.js code
angular.module('myApp.directives', []).
directive('appVersion', ['version', function(version) {
return function(scope, elm, attrs) {
elm.text(version);
};
}])
.directive('appAuthor', ['author', function(author) {
return function(scope, elm, attrs){
elm.text(author);
};
}]);
The above code worked completely worked fine and displayed version and author configured in service.js
The moment i modify my controller.js to include a new controller as below it stops working and nor the version nor the author is displayed.
The modified controller code is as below
function MyCtrl1() {}
MyCtrl1.$inject = [];
function MyCtrl2() {
}
MyCtrl2.$inject = [];
angular.module('myApp', ['ui.bootstrap']);
var TabsDemoCtrl = function ($scope) {
$scope.panes = [
{ title:"Dynamic Title 1", content:"Dynamic content 1" },
{ title:"Dynamic Title 2", content:"Dynamic content 2" }
];
};
TabsDemoCtrl.$inject = ['$scope'];
Any pointers why this thing is not working.
Looks like your problem is the redeclaration of myApp here:
angular.module('myApp', ['ui.bootstrap']);
I was able to reproduce your problem when I had
angular.module('myApp', ['myApp.services', 'myApp.directives']);
angular.module('myApp', ['ui.bootstrap']);
Switching it to
angular.module('myApp', ['myApp.services', 'myApp.directives', 'ui.bootstrap']);
made everything work again.

Categories