I have taken the sample project from the cordova-plugin-hotspot and tried building it into android application. But when I'm using that sample, I'm getting the module not defined error but I checked that the module has been defined in the html and in angular.module. So please someone help me to figure out what is the actual error. Below is that sample program.
index.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="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
</head>
<body ng-app = "starter">
<!--
The nav bar that will be updated as we navigate between views.
-->
<ion-nav-bar class="bar-stable" ng-controller = "HotSpotCtrl">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</body>
app.js
function onDeviceReady() {
// bootstrap app:
angular.bootstrap(document, ['starter']);
}
if (window.cordova) {
document.addEventListener('deviceready', onDeviceReady, false);
} else {
onDeviceReady();
}
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.services' is found in services.js
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'starter.controllers'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.constant('$ionicLoadingConfig', {
template: '<ion-spinner></ion-spinner> <br> Loading '
})
.config(function ($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
// places them at the bottom for all OS
$ionicConfigProvider.tabs.position('bottom');
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
// Each tab has its own nav history stack:
.state('tab.hotspot', {
url: '/hotspot',
views: {
'tab-hotspot': {
templateUrl: 'templates/tab-hotspot.html',
controller: 'HotSpotCtrl'
}
}
})
.state('tab.devices', {
url: '/devices',
views: {
'tab-devices': {
templateUrl: 'templates/tab-devices.html',
controller: 'DevicesCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tab/hotspot');
});
controller.js
angular.module('starter.controllers', [])
.controller('HotSpotCtrl', function ($scope, $ionicLoading, $timeout) {
var init = function () {
$ionicLoading.show();
// default to WPA2PSK
$scope.config = {
mode: 'WPA2PSK'
};
cordova.plugins.hotspot.isHotspotEnabled(function (enabled) {
$scope.isHotSpotActive = enabled;
$ionicLoading.hide();
}
);
};
// init controllers
init();
// API
$scope.start = function () {
$ionicLoading.show();
cordova.plugins.hotspot.createHotspot(
$scope.config.ssid, $scope.config.mode, $scope.config.password,
function () {
// delay UI refresh
$timeout(function () {
$ionicLoading.hide();
init();
}, 500);
}, function () {
$ionicLoading.hide();
alert('Hotspot creation failed');
}
);
};
$scope.stop = function () {
$ionicLoading.show();
cordova.plugins.hotspot.stopHotspot(
function () {
$ionicLoading.hide();
$scope.isHotSpotActive = false;
init();
}, function () {
alert('AP disabling failed');
}
);
};
})
.controller('DevicesCtrl', function ($scope) {
var init = function () {
cordova.plugins.hotspot.isHotspotEnabled(function (enabled) {
$scope.isHotSpotActive = enabled;
if (enabled) {
$scope.status = 'Reading devices ...';
cordova.plugins.hotspot.getAllHotspotDevices(
function (response) {
$scope.status = false;
$scope.devices = response;
}, function () {
$scope.status = false;
alert('Device listing failed.');
}
);
}
}, function () {
$scope.status = false;
}
);
};
// init controllers
init();
// API
$scope.refresh = function () {
init()
};
});
Related
I am trying to use require.js with Main.js and getting following error:
http://errors.angularjs.org/1.4.12/$injector/modulerr?p0=bleepMed&p1=Error%3
(http%3A%2F%2Flocalhost%3A8000%2Fjs%2Fvendor.min.js%3A25%3A274)
My Main.js
'use strict';
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
};
angular.module('bleepMed', [
' ui.router',
'angular-loading-bar',
'ngAnimate',
'ui.bootstrap',
'ui.bootstrap.datetimepicker',
'angular-ui-validator',
'toastr',
'angular-uuid',
'colorpicker.module',
'naif.base64',
'highcharts-ng',
'ui.gravatar',
'ds.clock',
'sun.scrollable',
'ngFileUpload',
'countTo',
'angularMoment',
'ngSanitize',
'textAngular',
'ui.grid',
'ui.grid.resizeColumns',
'ui.grid.pagination',
'ngDraggable',
'timer',
require('./common').name,
require('./config').name,
require('./modules').name,
require('./util').name
])
.config(['cfpLoadingBarProvider', '$urlRouterProvider', 'AppConfig', 'toastrConfig', '$locationProvider', function(cfpLoadingBarProvider, $urlRouterProvider, AppConfig, toastrConfig, $locationProvider) {
//for angular bar loading
cfpLoadingBarProvider.includeSpinner = false;
$urlRouterProvider.when('/', ['$state', 'loggedInUser', function($state, loggedInUser) {
if (!Object.keys(loggedInUser.getData()).length) {
$state.go('login');
} else {
$state.go('admin.home');
}
}]);
angular.extend(toastrConfig, AppConfig.toastr);
// $locationProvider.html5Mode(true).hashPrefix('*');
// $translateProvider
// .useStaticFilesLoader({
// prefix: '/translations/',
// suffix: '.json'
// })
// .preferredLanguage('en')
// .useMissingTranslationHandlerLog();
}])
// .constant('moment', require('moment-timezone'))
.run([
'$rootScope',
'$injector',
'loggedInUser',
'$state',
'toastr',
'$timeout',
'$window',
'AppConfig',
'API',
function($rootScope, $injector, loggedInUser, $state, toastr, $timeout, $window, AppConfig, API) {
console.log("in......");
$rootScope.googleChartLoaded = false;
$rootScope.picUrl = API.picUrl;
$rootScope.$on('$stateChangeStart', function(event, toState, fromState) {
if (Object.keys(loggedInUser.getData()).length && (toState.name.indexOf('login') > -1)) {
event.preventDefault();
}
if (!Object.keys(loggedInUser.getData()).length && (toState.name.indexOf('admin') > -1)) {
event.preventDefault();
$state.go('login');
}
});
$rootScope.$on('$stateChangeSuccess', function() {
$rootScope.loadingText = '';
$rootScope.pageLoading = false;
});
$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
$rootScope.pageLoading = false;
});
$rootScope.$on('invalidToken', function() {
$state.go('login');
});
//for google chart//
google.charts.load('current', {
'packages': ['corechart', 'bar']
});
function googleChartLoadedCallback() {
$timeout(function() {
// console.log('here in timeout');
$rootScope.googleChartLoaded = true;
$rootScope.$broadcast('chartLoaded', {});
}, 0);
}
google.charts.setOnLoadCallback(googleChartLoadedCallback);
$rootScope.goBack = function() {
$window.history.back();
};
//mqtt starts
$rootScope.client = mqtt.connect(API.mqtt);
$rootScope.client.on('connect', function() {
console.log('connected');
});
$rootScope.client.on('subscribe', function() {
console.log('subscribe');
});
}
]);
My index.html
<!DOCTYPE html>
<html ng-app="bleepMed">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1,
maximum-scale=1">
<!-- <base href="/"> -->
<title>Bleep Med</title>
<!--Stylesheet-->
<link rel="stylesheet" type="text/css" href="./css/vendor.min.css">
<link rel="stylesheet" type="text/css" href="./css/app.min.css">
</head>
<body>
<div ui-view ng-class="moduleClass" class="full-height ui-view-class">
</div>
<!-- <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCV7dBG_5koAJ_HmwRDEc7l4jezGbpHyfs&libraries=places">
</script> -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCCE7DhZbQJ8-ki453Z2JdGzPJdMZ5o5JM&libraries=places"></script>
<script type="text/javascript" src="https://code.highcharts.com/highcharts.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="resources/js/mqtt.js"></script>
<script src="./js/vendor.min.js"></script>
<script src="./js/main.min.js"></script>
</body>
</html>
I got an error that said I need to add ngroute to my app but I still get this error. Can anyone point me to what i might be doing wrong?
My exact error is:
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.2.1/$injector/modulerr?p0=bleepMed&p1=Error%3A%20%5B%24injector%3Amodulerr%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.2.1%2F%24injector%2Fmodulerr%3Fp0%3Dsun.scrollable%26p1%3DError%253A%2520%255B%2524injector%253Anomod%255D%2520http%253A%252F%252Ferrors.angularjs.org%252F1.2.1%252F%2524injector%252Fnomod%253Fp0%253Dsun.scrollable%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.2.1%252Fangular.min.js%253A6%253A447%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.2.1%252Fangular.min.js%253A20%253A159%250A%2520%2520%2520%2520at%2520a%2520(https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.2.1%252Fangular.min.js%253A19%253A353)%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.2.1%252Fangular.min.js%253A20%253A54%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.2.1%252Fangular.min.js%253A28%253A487%250A%2520%2520%2520%2520at%2520Array.forEach%2520(%253Canonymous%253E)%250A%2520%2520%2520%2520at%2520p%2520(https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.2.1%252Fangular.min.js%253A7%253A255)%250A%2520%2520%2520%2520at%2520e%2520(https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.2.1%252Fangular.min.js%253A28%253A427)%250A%2520%2520%2520%2520at%2520https%253A%252F%252Fajax.googleapis.com%252Fajax%252Flibs%252Fangularjs%252F1.2.1%252Fangular.min.js%253A28%253A504%250A%2520%2520%2520%2520at%2520Array.forEach%2520(%253Canonymous%253E)%0A%20%20%20%20at%20https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.1%2Fangular.min.js%3A6%3A447%0A%20%20%20%20at%20https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.1%2Fangular.min.js%3A29%3A279%0A%20%20%20%20at%20Array.forEach%20(%3Canonymous%3E)%0A%20%20%20%20at%20p%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.1%2Fangular.min.js%3A7%3A255)%0A%20%20%20%20at%20e%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.1%2Fangular.min.js%3A28%3A427)%0A%20%20%20%20at%20https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.1%2Fangular.min.js%3A28%3A504%0A%20%20%20%20at%20Array.forEach%20(%3Canonymous%3E)%0A%20%20%20%20at%20p%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.1%2Fangular.min.js%3A7%3A255)%0A%20%20%20%20at%20e%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.1%2Fangular.min.js%3A28%3A427)%0A%20%20%20%20at%20Yb%20(https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.1%2Fangular.min.js%3A32%3A462)
Angular throws this error when it fails to load any module.
In your example, there is a typo in ui.router. You added extra blank space before the module name which may throwing error.
Edit:
The error you copied shows that you are using module named as sun.scrollable is not loaded. Are you loading required module js file??
Django 1.11
Django REST Framework (DRF) 3.6
DRF-JWT 1.10
AngularJS 1.6.5
ui-router 1.0.3
Fairly new to all of this technology and have been messing with this issue for several days now. Learned about this stack (minus UI-router which I just switched to a week ago) through the following class and repository:
https://www.udemy.com/django-angularjs/learn/v4/overview
https://github.com/codingforentrepreneurs/Django-AngularJS/tree/master/src
These are the directories that are probably the most relevant to my issue:
Config and JS: https://github.com/codingforentrepreneurs/Django-AngularJS/tree/master/src/static/js/app
Login-required interceptor: https://github.com/codingforentrepreneurs/Django-AngularJS/tree/master/src/static/js/app/core/interceptors
Service, pages where login is required, and interceptor is utilized: https://github.com/codingforentrepreneurs/Django-AngularJS/tree/master/src/static/js/app/core/comment
I am trying to adapt it for my project.
I have read several tutorials on using ui-router purely for this purpose, but they don't seem to use DRF-JWT or are missing important steps that a newb like me needs.
Anyway, I have two urls:
/
/dashboard
The former is the login, /dashboard requires authorization and should route to / if the person isn't logged in. Before I started trying to implement this, one could just type in /dashboard without being authenticated and view it. I have verified that when a person logins in the token through DRF-JWT it is being generated and written to the cookie as I can console.log it on successful login.
Since I have been trying to implement this, I can't even get / to load. I get an $injector:modulerr issue that I can't resolve.
Code time:
I get the $injector:modulerr once I change:
// dashboard.module.js
angular.module('dashboard', ['chart.js']);
To
// dashboard.module.js
angular.module('dashboard', ['chart.js', 'interceptors']);
Other imperative JS:
// login_required.service.js
'use strict';
angular.
module('interceptors').
factory('LoginRequiredInterceptor', function($cookies, $location) {
return function(response) {
console.log('working')
console.log('interceptor error')
console.log(response)
if (response.status == 401){
var currentPath = $location.path();
console.log(currentPath)
if (currentPath == '/') {
$location.path('/')
} else {
$location.path('/').search('next', currentPath)
}
}
}
})
-
// interceptors.module.js
'use strict';
angular.module('interceptors', ['ngCookies']);
-
// dashboard.component.js
'use strict';
angular.module('dashboard').
component('dashboard', {
templateUrl: '/api/templates/dashboard.html',
controller: function($cookies, $location, $stateParams, $rootScope, $scope) {
// Nothing at this point
}
});
Really haven't updated the below from the project I cloned it from above:
// dashboard.service.js
'use strict';
angular.
module('dashboard').
factory('Dashboard', function(LoginRequiredInterceptor, $cookies, $httpParamSerializer, $location, $resource){
var token = $cookies.get("token")
if (token){
commentCreate["headers"] = {"Authorization": "JWT " + token}
commentDelete["headers"] = {"Authorization": "JWT " + token}
commentUpdate["headers"] = {"Authorization": "JWT " + token}
}
return $resource(url, {}, {
query: commentQuery,
get: commentGet,
create: commentCreate,
delete: commentDelete,
update: commentUpdate,
})
});
Lastly, the main config:
// app.config.js
'use strict';
angular.module('app').
config(
function(
$locationProvider,
$resourceProvider,
$stateProvider,
$urlRouterProvider,
$authProvider
) {
// Enable HTML5 mode
$locationProvider.html5Mode({
enabled:true
})
// Remove trailing slashes to avoid API issues
$resourceProvider.defaults.stripTrailingSlashes = false;
// Route handling if the URL does not match any of the below
// it will send the user to the login screen
$urlRouterProvider.otherwise('/');
$stateProvider
// The top URL (app/) is the login screen
.state('/', {
url: '/',
views: {
'content#': {
component: 'login'
}
}
})
// Logout and reroute to the login screen
.state('logout', {
redirectTo: '/'
})
// After successful login, the user is brought to the dashboard
// Parent of the states below it
.state('dashboard', {
url: '/dashboard',
views: {
'content#': {
component: 'dashboard'
}
},
})
// Test State1
.state('dashboard.test1', {
views: {
'dashboard#dashboard': {
template: '<p style="position: absolute;top: 110%; left: 50%">Test1</p>'
}
}
})
// Test State2
.state('dashboard.test2', {
views: {
'dashboard#dashboard': {
template: '<p style="position: absolute;top: 50%; left: 50%">Test2</p>'
}
}
})
});
Also, <scripts> I am reading in (at the bottom of my <body> tag):
<!-- base.html -->
<!-- Angular 1.x and Bootstrap UI libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js" integrity="sha256-zBy1l2WBAh2vPF8rnjFMUXujsfkKjya0Jy5j6yKj0+Q=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-cookies.min.js" integrity="sha256-tVvnbUkwgprwLlmcKyx6/dz+KifqSSJ41vvUGvL72QM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-resource.min.js" integrity="sha256-J9EYt6krcoClMPGCdI0BA5vhMVHU/lu9vSnhbx0vfAI=" crossorigin="anonymous"></script>
<!--
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-route.min.js" integrity="sha256-E6XubcgT4a601977ZZP4Yw/0UCB2/Ex+Bazst+JRw1U=" crossorigin="anonymous"></script>
-->
<!-- UI libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.js" integrity="sha256-w3THDDhkzdjMczax74BBlkhjBxWIGisjArsP5wIQSHc=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js" integrity="sha256-tyfWW2LtJQNI+l3F0h6xDV/ij6Mfn8lwSKHWOsmEgXM=" crossorigin="anonymous"></script>
<!-- Misc 3rd Part Libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/satellizer/0.14.1/satellizer.min.js" integrity="sha256-pcZRGEYkbl74zjS+YusQRvVWoFcwZTHLjmDCvbdX2ec=" crossorigin="anonymous"></script>
<!-- Chart related libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js" integrity="sha256-SiHXR50l06UwJvHhFY4e5vzwq75vEHH+8fFNpkXePr0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-chart.js/1.1.1/angular-chart.min.js" integrity="sha256-ydmVOl8gRR1E4yD1OC/aQdLNPCIKXSHIpl9yOu8EWek=" crossorigin="anonymous"></script>
<!-- Core application settings -->
<script src='{% static "js/app.module.js" %}' ></script>
<script src='{% static "js/app.config.js" %}' ></script>
<!-- Global application components -->
<script src='{% static "js/navbar/navbar.module.js" %}' ></script>
<script src='{% static "js/navbar/navbar.directive.js" %}' ></script>
<script src='{% static "js/sidebar/sidebar.module.js" %}' ></script>
<script src='{% static "js/sidebar/sidebar.directive.js" %}' ></script>
<!-- Page specific application componenets -->
<script src='{% static "js/login/login.module.js" %}' ></script>
<script src='{% static "js/login/login.component.js" %}' ></script>
<script src='{% static "js/dashboard/dashboard.module.js" %}' ></script>
<script src='{% static "js/dashboard/dashboard.component.js" %}' ></script>
Let me know if anything else would be helpful.
Well, I found a solution that seems to be working for me and is rather simple. There could be several issues with it, so feedback on why not to do this would be greatly appreciated.
I pretty much ditched the interceptors, services, etc.
Again, I really only have 2 URLs: '/' and '/dashboard'. The former is the login and the latter is where all the tools available to a user will be (eventually several dozen tools), but they will be child views of the parent dashboard. You can start to see this here:
// app.config.js
'use strict';
angular.module('app').
config(
function(
$locationProvider,
$resourceProvider,
$stateProvider,
$urlRouterProvider,
$authProvider
) {
// Enable HTML5 mode
$locationProvider.html5Mode({
enabled:true
})
// Remove trailing slashes to avoid API issues
$resourceProvider.defaults.stripTrailingSlashes = false;
// Route handling if the URL does not match any of the below
// it will send the user to the login screen
$urlRouterProvider.otherwise('/');
$stateProvider
// The top URL (app/) is the login screen
.state('/', {
url: '/',
views: {
'content#': {
component: 'login'
}
}
})
// Logout and reroute to the login screen
.state('logout', {
redirectTo: '/'
})
// After successful login, the user is brought to the dashboard
// Parent of the states below it
.state('dashboard', {
url: '/dashboard',
views: {
'content#': {
component: 'dashboard'
}
},
})
// Test child State1
.state('dashboard.test1', {
views: {
'dashboard#dashboard': {
template: '<p style="position: absolute;top: 110%; left: 50%">Test1</p>'
}
}
})
// Test child State2
.state('dashboard.test2', {
views: {
'dashboard#dashboard': {
template: '<p style="position: absolute;top: 50%; left: 50%">Test2</p>'
}
}
})
});
Here is the login where the JWT token is written to the cookie.
// login.component.js
'use strict';
angular.module('login').
component('login', {
templateUrl: 'api/templates/login.html',
controller: function($cookies, $http, $location, $stateParams, $rootScope, $scope) {
var loginUrl = 'api/users/login/'
$scope.loginError = {}
$scope.user = {}
$scope.$watch(function() {
if ($scope.user.password) {
$scope.loginError.password = ''
} else if ($scope.user.username) {
$scope.loginError.username = ''
}
})
var tokenExists = $cookies.get('token')
if (tokenExists) {
// verify token
$scope.loggedIn = true;
$cookies.remove('token')
$scope.user = {
username: $cookies.get('username')
}
// window.location.reload()
}
// Main login handling for user
$scope.doLogin = function(user) {
// console.log(user)
if (!user.username) {
$scope.loginError.username = ['This field may not be blank.']
}
if (!user.password) {
$scope.loginError.password = ['This field is required.']
}
// If both the username and the password are supplied then POST it to the login API URL
if (user.username && user.password) {
$http({
method: 'POST',
url: loginUrl,
data: {
username: user.username,
password: user.password
},
headers: {}
}).then(function successCallback(r_data, r_status, r_headers, r_config) {
// console.log(r_data.data)
$cookies.put('token', r_data.data.token)
$cookies.put('username', r_data.data.username)
var token = $cookies.get('token')
// console.log(token)
$location.path('/dashboard')
// window.location.reload()
}, function errorCallback(e_data, e_status, e_headers, e_config) {
// Check if this is a 400 error which is related to an invalid password
if (e_data.status == 400) {
$scope.loginError.invalid = ['The credentials entered are invalid.']
}
})
}
}
}
})
Then for the dashboard I just did the following:
// dashboard.component.js
'use strict';
angular.module('dashboard').
component('dashboard', {
templateUrl: '/api/templates/dashboard.html',
controller: function($cookies, $location, $stateParams, $rootScope, $scope) {
var token = $cookies.get('token')
console.log(token)
if (token) {
$location.path('/dashboard')
} else {
$location.path('/')
}
}
});
It seems to work how I expect it to:
if you try to go /dashboard it will route you to the login screen
if you login and are routed to /dashboard you can type in /dashboard to the URL and it displays it
if you logout, it will not allow you to view /dashboard by typing it in or hitting the back button in browser
it doesn't allow access to the subviews directly, which I think is just due to routing: that subviews can't be rendered if the parent view cannot.
Anyway, feedback would be greatly appreciated.
EDIT: Realizing how similar this is to the project I am copying, but instead of an interceptor I have it in in the dashboard component.
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>
I have the following code in my Auth factory:
login: function(user) {
return $http
.post('/login', user)
.then(function(response) {
Session.setUser(response.data);
$cookies.put('userId', response.data._id);
$state.go('home', { reload: true });
// $window.location.href = '/';
})
;
},
The problem is that my navbar doesn't get updated (I have properties in the view that are data bound to vm.currentUser; see below). It does when I use $window.location.href = '/', but doing that messes up my tests.
I figure that the solution would be to manually reload the navbar directive. How can I do that? This is what the directive currently looks like:
angular
.module('mean-starter')
.directive('navbar', navbar)
;
function navbar() {
return {
restrict: 'E',
templateUrl: '/components/navbar/navbar.directive.html',
controller: NavbarController,
controllerAs: 'vm'
};
}
function NavbarController(Auth) {
var vm = this;
Auth
.getCurrentUser()
.then(function(currentUser) {
vm.currentUser = currentUser;
})
;
vm.logout = function() {
Auth.logout();
};
}
ok, after you explained further what is broken I noticed that the problem is that in your factory you are not properly returning the deferred promise like deferred.resolve. I should explain, I'm specifically looking around the question of how to "manually reload a directive" because you should not have to manually reload a directive, that's an antipattern. Directives should take care of themselves.
I made a demo. After the proper Auth factory finishing it's thing, with deferred.resolve the directive updates all on it's own because the bound model has changed. Check it out, it solves your problem:
http://plnkr.co/edit/u1FakV?p=preview
var app = angular.module('plunker', []);
app.factory('Auth', ['$timeout', '$q',
function($timeout, $q) {
function getCurrentUserFake() {
var deferred = $q.defer();
setTimeout(function() {
deferred.resolve('Joe Smith');
}, 1000);
return deferred.promise;
}
function getCurrentUser() {
var deferred = $q.defer();
$http.get('/login')
.success(function(data) {
deferred.resolve(data)
})
.error(function(data) {
deferred.reject(data);
});
return deferred.promise;
}
return {
getCurrentUser: getCurrentUser,
getCurrentUserFake: getCurrentUserFake
};
}
]);
app.directive('navbar', navbar);
function navbar() {
return {
restrict: 'E',
template: '<div>{{vm.currentUser}}</div>',
controller: NavbarController,
controllerAs: 'vm'
};
}
function NavbarController(Auth) {
var vm = this;
vm.currentUser = 'logging in...';
Auth
.getCurrentUserFake()
.then(function(currentUser) {
console.log(currentUser);
vm.currentUser = currentUser;
});
vm.logout = function() {
Auth.logout();
};
}
html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="app.js"></script>
</head>
<body>
<navbar></navbar>
</body>
</html>
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");
}]);
});