I am working on an application in which I am trying to load angular JS using require JS. My click event is not working in my code. Can someone pls help :
<!DOCTYPE html>
<html lang="en" data-ng-app="myApp">
<body class="internal" >
<div id="contentContainer" class="stratum" data-ng-controller="appController">
<div id="main-bar" class="row">
<div id="go" class="column column.one-quarter-">
<div class="btnLabel"><label for="submitBtn"></label></div>
<div><button id="submitBtn" ng-click="getBarChartData()"> GO</button></div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
var contextPath = "<%= request.getContextPath() %>";
var appUrl = "<%= request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() %>";
var isSessionExpired = false;
</script>
<!-- JavaScripts Require JS Library and App JS Files -->
<script type="text/javascript" data-main="<%=request.getContextPath() %>/resources/js/app/uptimeReport.js" src="<%=request.getContextPath() %>/resources/js/libs/requirejs/require.js"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/resources/js/app/main-built.js"></script>
</body>
</html>
App.js
/*global require*/
'use strict';
require([
'angular'
], function (angular) {
require([
'controller/environmentController'
], function (appCtrl) {
angular.
module('myApp',[]).
controller('appController', appCtrl);
angular.bootstrap(document, ['myApp']);
console.log("in App.js");
});
});
uptimeReport.js
/*global require*/
'use strict';
requirejs.config(
{
/** set up any additional paths that are outside of your application base * */
paths:
{
angular: contextPath + '/resources/js/libs/angularJS/angular',
},
/**
* The following is not required in this example, but it is an example of
* how to make non-AMD java script compatible with require
*/
shim: {
angular: {
exports: 'angular'
}
},
deps: ['app']
});
controller/environmentController.js
/*global define*/
'use strict';
/**
* The main controller for the app. The controller:
* - retrieves and persist the model via the todoStorage service
* - exposes the model to the template and provides event handlers
*/
define([
'angular'
], function (angular) {
return ['$scope', '$http',
function($scope, $http) {
console.log("in controller123.js");
var businessUrl="http://localhost:8080/UptimeReport/services/getBusinessAreas";
var appUrl="http://localhost:8080/UptimeReport/services/getApplications";
var envUrl="http://localhost:8080/UptimeReport/services/getEnvironments";
$http.get(businessUrl).then(function(response) {
$scope.business = response.data;
});
$http.get(appUrl).then(function(response) {
$scope.application = response.data;
});
$http.get(envUrl).then(function(response) {
$scope.environment = response.data;
});
}];
});
you should bind the getBarChartData function in your $scope
to be able to use event bind
ng-click="getBarChartData()"
if you did not bind the function to the $scope you can use it like
ng-click="Controller.getBarChartData()"
Related
I am tring to get the data using rxjs from promise method, and once it is success am subscribing it and passing it to my scope.
I can see the response object attached to my scope, but in UI, it is not getting mapped.
This is what I tried.
index html:
<html>
<head></head>
<body>
<my-component></my-component>
<script src="rx.lite.js"></script>
<script src="angular.min.js"></script>
<script src="rx.angular.js"></script>
<script src="app.js"></script>
<script src="service.js"></script>
<script src="component.js"></script>
</body>
</html>
app.js:
(function() {
'use strict';
angular.module('app', ['rx']);
})();
service.js:
;(function (undefined) {
'use strict';
angular.module('app').factory('myService', ['$http', '$q', 'rx',function($http, $q, rx) {
function httpReq(configObj){
var deferred = $http(configObj);
return rx.Observable
.fromPromise(deferred)
.map(function(response){ return response.data; });
}
return {
httpReq : httpReq
}
}]);
}.call(this));
component.js:
;(function (undefined) {
'use strict';
angular.module('app').component('myComponent', {
templateUrl: "myComponent.tpl.html",
controller: ['myService', 'rx', Ctrl]
});
function Ctrl(myService, rx) {
var $ctrl = this;
myService.httpReq({ url: ' http://localhost:3000/posts/1', method: 'GET'})
.subscribe(function(val) {
$ctrl.list = val;
}.bind(this));
}
}.call(this));
myComponent.tpl.html:
<div ng-if="$ctrl.list">{{$ctrl.list}}</div>
You have to call $apply() because $scope is modified outside of the $digest cycle (not sure though).
I am working through some Angular examples and got an interesting exception-scenario & was wondering why it happens.
The Scenario:
IT FAILS
- When I create my controller in a $(document)ready(function{ ... }) block
IT WORKS
- When I create my controller outright
Why?
I'm sure your not supposed to bring-in jQuery like this, but still, why does it fail?
In The Head:
<script type="text/javascript">
var appName = 'personal.web';
var application = angular.module(appName, ['ngRoute']);
application.config(function ($httpProvider, $routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide, $locationProvider) {
// REQUIRED: Enables "late" registration
application.register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
application.run(function ($http) {
console.log(appName + ' is running');
});
</script>
In The Body:
<div class="container" ng-controller="HomeIndexController">
<div class="row">
<h3>Home Body</h3>
</div>
</div>
<div class="container">
<div class="row" ng-view></div>
</div>
At Page Bottom:
FAILS: A controller with this name is not registered
<script type="text/javascript">
$(document).ready(function () {
application.controller('HomeIndexController', function ($scope) {
var vm = this;
console.log('HomeIndexController');
});
}); </script>
WORKS
application.controller('HomeIndexController', function ($scope) {
var vm = this;
console.log('HomeIndexController');
});
Reason for it fails is $(document).ready, angular will register controllers, services and so on before rendering views. but here you are defining controller in document.ready which is too late that angular will throw error of cannot find controller.
It fails because document is ready after angular has started, so your app is looking for a component that does not exist yet. and it fails...
index.html
<body>
<div ng-app="myapp">
<div ng-controller="HelloController" >
<h2>Welcome {{hello.title}} to the world Mr. {{hello.myname}}!</h2>
</div>
</div>
<script src="cordova.js"></script>
<script src="bower_components/angular/angular.min.js"></script>
<script src="js/index.js"></script>
</body>
index.js
document.addEventListener('deviceready', function() {
var myapp = angular.module("myapp", []);
myapp.controller("HelloController", function($scope) {
console.log("inside controller");
$scope.hello = {};
$scope.hello.title = "AngularJS";
$scope.hello.myname = "hello";
});
}, false);
Error displayed in logcat
02-11 14:52:19.835: I/chromium(2955): [INFO:CONSOLE(40)] "Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.5.0/$injector/modulerr?p0=myapp&p1=Error%3A%20%5B%24injector%3Anomod%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.5.0%2F%24injector%2Fnomod%3Fp0%3Dmyapp%0A%20%20%20%20at%20Error%20(native)%0A%20%20%20%20at%20file%3A%2F%2F%2Fandroid_asset%2Fwww%2Fbower_components%2Fangular%2Fangular.min.js%3A6%3A416%0A%20%20%20%20at%20file%3A%2F%2F%2Fandroid_asset%2Fwww%2Fbower_components%2Fangular%2Fangular.min.js%3A25%3A136%0A%20%20%20%20at%20b%20(file%3A%2F%2F%2Fandroid_asset%2Fwww%2Fbower_components%2Fangular%2Fangular.min.js%3A24%3A188)%0A%20%20%20%20at%20file%3A%2F%2F%2Fandroid_asset%2Fwww%2Fbower_components%2Fangular%2Fangular.min.js%3A24%3A431%0A%20%20%20%20at%20file%3A%2F%2F%2Fandroid_asset%2Fwww%2Fbower_components%2Fangular%2Fangular.min.js%3A39%3A357%0A%20%20%20%20at%20n%20(file%3A%2F%2F%2Fandroid_asset%2Fwww%2Fbower_components%2Fangular%2Fangular.min.js%3A7%3A355)%0A%20%20%20%20at%20g%20(file%3A%2F%2F%2Fandroid_asset%2Fwww%2Fbower_components%2Fangular%2Fangular.min.js%3A39%3A135)%0A%20%20%20%20at%20fb%20(file%3A%2F%2F%2Fandroid_asset%2Fwww%2Fbower_components%2Fangular%2Fangular.min.js%3A43%3A164)%0A%20%20%20%20at%20Ac.c%20(file%3A%2F%2F%2Fandroid_asset%2Fwww%2Fbower_components%2Fangular%2Fangular.min.js%3A20%3A449)", source: file:///android_asset/www/bower_components/angular/angular.min.js (40)
Detailed error displayed in catlog
02-11 15:35:37.334: E/Web Console(24865): Uncaught Error: [$injector:nomod] Module 'myapp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
What I am missing, The same code code works in a browser
I would recommend you to use RequireJS technique
It requires multiple files as below
index.html
<body>
<div id="controller" ng-app="app" ng-controller="HelloController" style="display:none">
<h2>Welcome {{hello.title}} to the world Mr. {{hello.myname}}!</h2>
</div>
<script src="cordova.js"></script>
<script src="bower_components/requirejs/require.js" data-main="js/main.js"></script>
</body>
main.js
require.config({
paths: {
'domReady': '../bower_components/domReady/domReady',
'angular': '../bower_components/angular/angular'
},
shim: {
'angular': {
exports: 'angular'
}
},
deps: ['./bootstrap']
});
bootstrap.js
define(['require','angular','app'], function (require, ng) {
require(['domReady!'], function (document) {
ng.bootstrap(document, ['app']);
});
});
app.js
define(['angular'], function (ng) {
var mod = ng.module('app', []);
mod.controller("HelloController", function($scope) {
$scope.hello = {
title: "angularjs",
myname: "hello"
}
document.getElementById("controller").style.display = "block";
});
return mod;
});
The reason we are using shim in the require.config is that the angularJS does not support AMD so we expose it as an object via RequireJS
I used document.getElementById("controller").style.display = "block"; to avoid the template html to appear without the values rendered
I'm using ngCordova "Network Information" plugin to get the online/offline status of the host device. I have followed this tutorial (which excellent, as are his other posts):
Josh Morony - Monitoring Online and Offline States in an Ionic Application
I have implemented the "ConnectivityMonitor" service as described in the article.
In one of my controllers/templates it works perfectly:
(function() {
'use strict';
angular
.module('myApp')
.controller('ResearchController', ResearchController);
ResearchController.$inject = ['$scope', '$stateParams', 'MyApi', 'ConnectivityMonitor'];
function ResearchController($scope, $stateParams, MyApi, ConnectivityMonitor) {
var vm = this;
vm.isOnline = ConnectivityMonitor.isOnline();
...
}
<ion-view title="RESEARCH" ng-controller="ResearchController as vm" >
<ion-content>
<div>
ONLINE: {{vm.isOnline}}
</div>
</ion-content>
</ion-view>
Result:
ONLINE: true
However, in another controller/template this does not work and I have been at this for hours and hours:
(function() {
'use strict';
angular
.module('MyApp')
.controller('HomeController', HomeController);
HomeController.$inject = ['$scope','ConnectivityMonitor'];
function HomeController($scope, ConnectivityMonitor) {
var vm = this;
vm.isOnline = ConnectivityMonitor.isOnline();
activate();
////////////////
function activate() {
}
}
})();
<ion-content class="background" ng-controller="HomeController as vm">
<p>ONLINE: {{vm.isOnline}}</p>
</ion-content>
Result:
ONLINE: {{vm.isOnline}}
Here ^^^ it seems that angular is not performing the databinding. I have all of my relevant controllers in index.html, as well as angularjs references.
Here is my implementation of the "ConnectivityMonitor" service:
(function() {
'use strict';
// http://www.joshmorony.com/monitoring-online-and-offline-states-in-an-ionic-application/
angular.module('MyApp').factory('ConnectivityMonitor', ['$rootScope', '$cordovaNetwork', connectivityMonitor]);
function connectivityMonitor($rootScope, $cordovaNetwork) {
return {
isOnline: function () {
if (ionic.Platform.isWebView()) {
return $cordovaNetwork.isOnline();
} else {
return navigator.onLine;
}
},
isOffline: function () {
if (ionic.Platform.isWebView()) {
return !$cordovaNetwork.isOnline();
} else {
return !navigator.onLine;
}
}
};
}
}
)();
Any idea why this would not be working? I'm new to AngularJS and Ionic so I'm thinking there is some nuance or convention that I'm overlooking. Thanks.
[ UPDATE 1 ]
I recreated this issue in an ionic starter app. There are two templates: Home.html and Workshere.html, with respective controllers. The online status is correctly displayed in the "Workshere" state, and is incorrect in the "Home" state. Also, adding the HomeController to Home.html (via ng-controller) seems to kill all interactivity on that page, can't even click the "Go to Workshere" link.
Home.html and home state is the default state for the MyApp. I'm starting to think that this is a timing issue an ConnectivityMonitor is not ready when the home state loads.
Code follows:
Home.html
<ion-view>
<ion-content ng-controller="HomeController">
<br/><br/><br/>
<p>HOME</p>
<p>ONLINE: {{vm}}</p>
<br/><br/>
<a ui-sref="workshere">Go to WorksHere</a>
</ion-content>
</ion-view>
home.controller.js
(function() {
'use strict';
angular
.module('myApp')
.controller('HomeController', HomeController);
HomeController.$inject = ['$scope','ConnectivityMonitor'];
function HomeController($scope, ConnectivityMonitor) {
$scope.vm = ConnectivityMonitor.isOnline();
activate();
////////////////
function activate() {
}
}
})();
Workshere.html
<ion-view ng-controller="WorkshereController as vm" >
<ion-content>
<br/><br/><br/>
<p>WORKS HERE</p>
<p>ONLINE: {{vm.isOnline}}</p>
<br/><br/>
<a ui-sref="home">Go to Home</a>
</ion-content>
</ion-view>
workshere.controller.js
(function() {
'use strict';
angular
.module('myApp')
.controller('WorkshereController', WorkshereController);
WorkshereController.$inject = ['$scope', 'ConnectivityMonitor'];
function WorkshereController($scope, ConnectivityMonitor) {
var vm = this;
vm.isOnline = ConnectivityMonitor.isOnline();
activate();
////////////////
function activate() {
}
}
})();
app.js
angular.module('myApp', ['ionic', 'ngCordova'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
// Don't remove this line unless you know what you are doing. It stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home.html'
})
.state('workshere', {
url: 'workshere',
templateUrl: 'workshere.html'
});
$urlRouterProvider.otherwise('/');
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="lib/ngCordova/dist/ng-cordova.js"></script>
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/connectivityMonitor.js"></script>
<script src="js/home.controller.js"></script>
<script src="js/workshere.controller.js"></script>
</head>
<body ng-app="myApp">
<ion-nav-view>
</ion-nav-view>
</body>
</html>
ConnectivityMonitor.js
(function() {
'use strict';
// http://www.joshmorony.com/monitoring-online-and-offline-states-in-an-ionic-application/
angular.module('myApp').factory('ConnectivityMonitor', ['$rootScope', '$cordovaNetwork', connectivityMonitor]);
function connectivityMonitor($rootScope, $cordovaNetwork) {
return {
isOnline: function () {
if (ionic.Platform.isWebView()) {
return $cordovaNetwork.isOnline();
} else {
return navigator.onLine;
}
},
isOffline: function () {
if (ionic.Platform.isWebView()) {
return !$cordovaNetwork.isOnline();
} else {
return !navigator.onLine;
}
},
startWatching: function(){
if(ionic.Platform.isWebView()){
$rootScope.$on('$cordovaNetwork:online', function(event, networkState){
console.log("went online");
});
$rootScope.$on('$cordovaNetwork:offline', function(event, networkState){
console.log("went offline");
});
}
else {
window.addEventListener("online", function(e) {
console.log("went online");
}, false);
window.addEventListener("offline", function(e) {
console.log("went offline");
}, false);
}
}
};
}
}
)();
Please see comments at the "UPDATE 1" marker.
Why don't you try it this way:
function HomeController($scope, ConnectivityMonitor) {
$scope.vm = ConnectivityMonitor.isOnline();
}
and for view
<ion-content class="background">
<p>ONLINE: {{vm}}</p>
</ion-content>
could you please tell me how to bind click event using require js + angularjs
I try to bind the click event but it is bind the click event
Here is my code
index.html
<!DOCTYPE html>
<html>
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<head>
<link type="text/css" href="http://code.ionicframework.com/1.0.0-beta.1/css/ionic.css" rel="stylesheet" />
</head>
<body>
<ion-nav-view animation="slide-left-right"></ion-nav-view>
<script data-main="main" src="lib/require.js"></script>
</body>
</html>
main.js
requirejs.config({
paths: {
ionic:'lib/ionic.bundle'
},
shim: {
ionic : {exports : 'ionic'}
}, priority: [
'ionic'
],
deps: [
'bootstrap'
]
});
bootstrap.js
/*global define, require, console, cordova, navigator */
define(['ionic', 'app', 'routes'], function (ionic, angular, app) {
'use strict';
var $html,
onDeviceReady = function () {
angular.bootstrap(document, [app.name]);
};
document.addEventListener("deviceready", onDeviceReady, false);
if (typeof cordova === 'undefined') {
$html = angular.element(document.getElementsByTagName('html')[0]);
angular.element().ready(function () {
try {
angular.bootstrap(document, [app.name]);
} catch (e) {
console.error(e.stack || e.message || e);
}
});
}
});
app.js
/*global define, require */
define(['ionic'],
function (angular) {
'use strict';
var app = angular.module('app', [
'ionic']);
return app;
});
You have a few bugs in your code... too many too list them all. See Plunker for the corrections.
The module ionic should be exported as angular.
requirejs.config({
paths: {
ionic:'lib/ionic.bundle'
},
shim: {
ionic : {exports : 'angular'}
}, priority: [
'ionic'
],
deps: [
'bootstrap'
]
});
Ionic/Angular must be loaded first - or angular can't initialize itself.
In the routes you have to reference the controller by name - not by location
/*global define, require */
define(['app'], function (app) {
'use strict';
app.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: "/login",
templateUrl: "login.html",
controller: 'controllers/LoginCtrl' // <-- should be 'LoginCtrl'
})
$urlRouterProvider.otherwise("/login");
}]);
});