Trying to integrate Phonegap Connection API with AngularJS - angularjs

I'm trying to use PhoneGap Connection API inside my Angular/Ionic project. What I want is to check the user's network and if it's NONE I want to show a specific div and if it's not NONE, show another div by using the ng-show directive.
Here is my code so far:
controller.js
.controller('LoginCtrl', function($scope, CheckConnection) {
$scope.net = CheckConnection.networkState();
})
.factory('cordovaReady', function() {
return function (fn) {
var queue = [];
var impl = function () {
queue.push(Array.prototype.slice.call(arguments));
};
document.addEventListener('deviceready', function () {
queue.forEach(function (args) {
fn.apply(this, args);
});
impl = fn;
}, false);
return function () {
return impl.apply(this, arguments);
};
};
})
.factory('CheckConnection', function(cordovaReady) {
return {
networkState: cordovaReady(function() {
var net = navigator.connection.type;
if(net == 'none') {
var internet = false;
} else {
var internet = true;
}
return internet;
})
};
})
view.html
<ion-nav-view name="login">
<div ng-hide="LoginCtrl.net">
NO CONNECTION {{net}}
</div>
<div ng-show="LoginCtrl.net">
CONNECTED {{net}}
</div>
</ion-nav-view>
I'm pretty new with Angular and PhoneGap so this issue may be very simple to solve but I just can't figure it out :( Any help will be much appreciated, thanks!

try this:
<ion-nav-view name="login" ng-controller="LoginCtrl">
<div ng-hide="net">
NO CONNECTION {{net}}
</div>
<div ng-show="net">
CONNECTED {{net}}
</div>

Ok, I found the solution! Angular has it's own way to check connection so I don't even need PhoneGap for this.
Here is my new controller.js:
.controller('LoginCtrl', function($window, $scope ) {
$scope.online = navigator.onLine;
$window.addEventListener("offline", function () {
$scope.$apply(function() {
$scope.online = false;
});
}, false);
$window.addEventListener("online", function () {
$scope.$apply(function() {
$scope.online = true;
});
}, false);
})
And view.html
<ion-nav-view name="login">
<div ng-hide="online">
NO CONNECTION
</div>
<div ng-show="online">
CONNECTED
</div>
</ion-nav-view>
Hope it helps someone else :D

Related

Ng-Click not working on mobile devices. How to change to ngTouch

I have a website which uses angular.js. The ng-click is working fine on laptop/desktop but not on mobile devices. From my research, I learned that i need to use ngTouch and I undertand that. My problem is that I am not a programmer and does not know how to do it.
I am hoping that there is someone who can help me or provide me with the right step or code. this is my code:
<div class="container" ng-controller="MessageBoardCtrl">
<div class="span6">
<div class="row-fluid item" ng-repeat="item in items" ui-animate>
<div class="span2"><img src="../images/post.png" width="48px" height="48px"/></div>
<div class=" well well-small">
<p>{{item.message}}</p>
</div>
</div>
</div>
<div class="span6">
<div class='well'>
<button class="btn btn-primary" ng-click="sendMessage()">Share</button>
Here is the javascript:
<script src="../templates/js/jquery.js"></script>
<script src="../templates/js/angular.js"></script>
<script src="../templates/js/angular-ui.js"></script>
<script src="../templates/js/angular-touch.js"></script>
<script src="../templates/js/angular-touch.min.js"></script>
<script>
function MessageBoardCtrl($scope, $http, $timeout) {
$scope.items = [];
$scope.message = '';
$scope.email = '';
$scope.lastTime = 0;
$scope.refreshMessages = function() {
$http.get('../templates/faucet.php/messages?time=' + $scope.lastTime).success(function(data) {
for(id in data) {
item = data[id];
$scope.items.unshift(item);
if($scope.lastTime<item.time)
$scope.lastTime = item.time;
}
});
}
$scope.sendMessage = function() {
if(!$scope.message)
return;
$http.post('../templates/faucet.php/add_message', {message: $scope.message, email: $scope.email}).success(function() {
$scope.message = '';
});
}
$scope.periodicRefresh = function() {
$scope.refreshMessages();
$timeout($scope.periodicRefresh, 5000, true);
}
$scope.refreshMessages();
}
</script>
Can someone give me a clean code based on the above that will work for ngtouch and instruction as well. Thanks in advance.
You can write your own directive for touch event. Below is an example directive to handle touch events. The directive below only fire the event in case of touch/long touch. scope.isMoved will prevent firing event when user tap on screen and move they finger around.
function directive($timeout) {
var dir = {
link: link,
restrict: 'A',
scope: {
onTouch: '&'
}
};
return dir;
function link(scope, element) {
scope.isMoved = false;
$timeout(function () {
// user start tap on screen
element.bind('touchstart', function () {
scope.isMoved = false;
});
element.bind('touchend click', function (evt) {
if (!scope.isMoved) {
scope.onTouch(evt);
}
});
//
element.bind('touchmove', function () {
scope.isMoved = true;
});
});
}
}
In HTML:
<a on-touch="someFunction()"> Touch</a>

cordova plugin is not ready

I have a plugin to get information from DB, then display the information on the page. But I can't get it work when the page is loaded. It only works in a event handler.
I have tried to bootstrap my app in 'deviceready' event. Still don't work.
Please help me! Thanks!
The index.html file:
<body ng-controller='loginCtl'> {{company}}
<div class="list list-inset " style="margin-top:20px;">
<button class="button button-block button-calm" ng-click="login()">Login</button>
</div>
</body>
The app.js file:
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady(){
var body = document.getElementsByTagName("body")[0];
angular.bootstrap(body,['starter']);
//company =myplugin.getCompany(); -- doesn't work here
}
angular.module('starter', ['ionic','starter.controllers'])
.run(function($ionicPlatform) {
//......
});
angular.module('starter.controllers', [])
.controller('loginCtl', function($scope) {
//$scope.company = myplugin.getCompany(); --- doesn't work at here
$scope.login=function(){
company =myplugin.getCompany(); //work at here
$scope.company = company;
};
});
Thanks for comments. I finally resolved this issue by copying device plugin. My plugin.js is not correct.
This is my original code, which only works in an event handler.
var myplugin = {
getCompany:function() {
exec(function(info)
{company=info.company;},
null, "Myplugin", "getLoginInfo", []);
return company;
}
};
module.exports = myplugin;
This is copied from cordova-plugin-device, which works in "deviceready" event:
channel.createSticky('onCordovaMyReady');
// Tell cordova channel to wait on the CordovaInfoReady event
channel.waitForInitialization('onCordovaMyReady');
function Myplugin() {
this.company = 'none';
var me = this;
channel.onCordovaReady.subscribe(function() {
me.getLoginInfo(function(info) {
me.company = info.company;
channel.onCordovaMyReady.fire();
},
function(e) {
utils.alert("[ERROR] Error initializing Cordova: " + e);
});
});
}
Myplugin.prototype.getLoginInfo = function(successCallback, errorCallback) {
exec(successCallback, errorCallback, "Myplugin", "getLoginInfo", []);
};
module.exports = new Myplugin();
});

AngularJS HotTowel invoke spinner during ajax call

I am trying to invoking the spinner during any xhr call within the application. Whereas the spinner appeared when I click at menu or route to different page.
Index page
<aside class="main-sidebar">
<!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar">
<!-- Sidebar user panel (optional) -->
<div data-cc-sidebar data-ng-controller="sidebar as vm">
<ul class="sidebar-menu">
<li data-ng-repeat="r in vm.navRoutes">
</li>
</ul>
</div>
</section>
<!-- /.sidebar -->
</aside>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper" data-ng-controller="shell as vm">
<!-- Content Header (Page header) -->
<section class="content-header"></section>
<!-- Main content -->
<section class="content">
<!-- Your Page Content Here -->
<div data-ng-show="vm.isBusy" class="page-splash dissolve-animation">
<div data-cc-spinner="vm.spinnerOptions"></div>
<div class="page-splash-message page-splash-message-subtle">{{vm.busyMessage}}</div>
</div>
<div data-ng-view class="shuffle-animation"></div>
</section><!-- /.content -->
</div><!-- /.content-wrapper -->
Shell.js
I have changed the shell.js file according to following instruction.
From
$rootScope.$on(events.spinnerToggle, function (data))
To
$rootScope.$on(events.spinnerToggle, function (event, data))
And found from following link comments
http://johnpapa.net/hot-towel-angular/
(function () {
'use strict';
var controllerId = 'shell';
angular.module('app').controller(controllerId,
['$rootScope', 'common', 'config', shell]);
function shell($rootScope, common, config) {
var vm = this;
var logSuccess = common.logger.getLogFn(controllerId, 'success');
var events = config.events;
vm.busyMessage = 'Please wait ...';
vm.isBusy = true;
vm.spinnerOptions = {
radius: 40,
lines: 7,
length: 0,
width: 30,
speed: 1.7,
corners: 1.0,
trail: 100,
color: '#F58A00'
};
activate();
function activate() {
logSuccess('SIPPRES loaded!', null, true);
common.activateController([], controllerId);
}
function toggleSpinner(on) { vm.isBusy = on; }
$rootScope.$on('$routeChangeStart',
function (event, next, current) { toggleSpinner(true); }
);
$rootScope.$on(events.controllerActivateSuccess,
function (data) { toggleSpinner(false); }
);
$rootScope.$on(events.spinnerToggle,
function (event,data) { toggleSpinner(data.show); }
);
};
})();
Directive looks like
app.directive('ccSpinner', ['$window', function ($window) {
// Description:
// Creates a new Spinner and sets its options
// Usage:
// <div data-cc-spinner="vm.spinnerOptions"></div>
var directive = {
link: link,
restrict: 'A'
};
return directive;
function link(scope, element, attrs) {
scope.spinner = null;
scope.$watch(attrs.ccSpinner, function (options) {
if (scope.spinner) {
scope.spinner.stop();
}
scope.spinner = new $window.Spinner(options);
scope.spinner.spin(element[0]);
}, true);
}
}]);
Thank you
I found my solution. Above code just working fine. Unfortunately, I placed my spinner.spinnerShow(); at wrong place in controller. Bellow controller function just working fine.
function updateColor(updatedColor) {
spinner.spinnerShow();
return datacontextSetting.updateColor(updatedColor).then(function (data) {
$scope.newColor = data;
$uibModalInstance.close($scope.newColor);
}, function (response) {
$scope.frmColor.$valid = false;
// Here is where we can catch the errors and start using the response.
if (!angular.isUndefined(response.statusCode)) {
$scope.errorMessage = response.statusCode + "\n";
}
if (response.modelState) {
for (var key in response.modelState) {
$scope.errorMessage += response.modelState[key] + "\n";
}
}
if (response.message) {
$scope.errorMessage += response.message;
}
}).finally(function () {
spinner.spinnerHide();
});
};
Thanks

AngularJs requires page refresh after API call

I am writing an angularjs app. The requirement is to display the user's data once the user logs in. So when an user successfully logs in, he/she is routed to the next view. My application is working fine upto this point. Now as the next view loads I need to display the existing records of the user. However at this point I see a blank page, I can clearly see in the console that the data is being returned but it is not binding. I have used $scope.$watch, $scope.$apply, even tried to call scope on the UI element but they all result in digest already in progress. What should I do? The page loads if I do a refresh
(function () {
"use strict";
angular.module("app-newslist")
.controller("newsController", newsController);
function newsController($http,$q,newsService,$scope,$timeout)
{
var vm = this;
$scope.$watch(vm);
vm.news = [];
vm.GetTopNews = function () {
console.log("Inside GetTopNews");
newsService.GetNewsList().
then(function (response)
{
angular.copy(response.data, vm.news);
}, function () {
alert("COULD NOT RETRIEVE NEWS LIST");
});
};
var el = angular.element($('#HidNews'));
//el.$scope().$apply();
//el.scope().$apply();
var scpe = el.scope();
scpe.$apply(vm.GetTopNews());
//scpe.$apply();
}
})();
Thanks for reading
you don't show how you're binding this in your template.. I tried to recreate to give you a good idea.
I think the problem is the way you're handling your promise from your newsService. Try looking at $q Promises. vm.news is being updated by a function outside of angular. use $scope.$apply to force refresh.
the original fiddle is here and a working example here
(function() {
"use strict";
var app = angular.module("app-newslist", [])
.controller("newsController", newsController)
.service("newsService", newsService);
newsController.$inject = ['$http', 'newsService', '$scope']
newsService.$inject = ['$timeout']
angular.bootstrap(document, [app.name]);
function newsController($http, newsService, $scope) {
var vm = this;
vm.news = $scope.news = [];
vm.service = newsService;
console.warn(newsService)
vm.message = "Angular is Working!";
vm.GetTopNews = function() {
console.log("Inside GetTopNews");
newsService.GetNewsList().
then(function(response) {
$scope.$apply(function() {
$scope.news.length > 0 ? $scope.news.length = 0 : null;
response.data.forEach(function(n) {
$scope.news.push(n)
});
console.log("VM", vm);
})
}, function() {
alert("COULD NOT RETRIEVE NEWS LIST");
});
};
}
function newsService($timeout) {
return {
GetNewsList: function() {
return new Promise(function(res, rej) {
$timeout(function() {
console.log("Waited 2 seconds: Returning");
res({
data: ["This should do the trick!"]
});
}, 2000);
})
}
}
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.9/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js"></script>
<body>
<div class="main">
<div class="body" ng-controller="newsController as vm">
Testing: {{ vm.message }}
<br>{{ vm.news }}
<br>{{ vm }}
<br>
<button class="getTopNewsBtn" ng-click="vm.GetTopNews()">Get News</button>
<br>
<ul class="getTopNews">
<li class="news-item" ng-repeat="news in vm.news track by $index">
{{ news | json }}
</li>
</ul>
</div>
</div>
</body>

Refresh a controller from another controller in Angular

In order to have two controllers speak to each other in Angular, it is recommended to create a common service which is made accessible to both controllers. I've attempted to illustrate this in a very simple fiddle. Depending on which button you press, the app is supposed to tailor the message below the buttons.
So why isn't this working? Am I missing something obvious or more fundamental?
HTML
<div ng-controller="ControllerOne">
<button ng-click="setNumber(1)">One</button>
<button ng-click="setNumber(2)">Two</button>
</div>
<div ng-controller="ControllerTwo">{{number}} was chosen!</div>
JavaScript
var app = angular.module('app', []);
app.factory("Service", function () {
var number = 1;
function getNumber() {
return number;
}
function setNumber(newNumber) {
number = newNumber;
}
return {
getNumber: getNumber,
setNumber: setNumber,
}
});
function ControllerOne($scope, Service) {
$scope.setNumber = Service.setNumber;
}
function ControllerTwo($scope, Service) {
$scope.number = Service.getNumber();
}
Try creating a watch in your controller:
$scope.$watch(function () { return Service.getNumber(); },
function (value) {
$scope.number = value;
}
);
Here is a working fiddle http://jsfiddle.net/YFbC2/
Seems like problem with property that holds a primitive value. So you can make these changes:
app.factory("Service", function () {
var number = {val: 1};
function getNumber() {
return number;
}
function setNumber(newNumber) {
number.val = newNumber;
}
return {
getNumber: getNumber,
setNumber: setNumber,
}
});
See fiddle
Just call in HTML Service.getNumber() and in controller ControllerTwo call Service like:
$scope.Service = Service;
Example:
HTML
<div ng-controller="ControllerOne">
<button ng-click="setNumber(1)">One</button>
<button ng-click="setNumber(2)">Two</button>
</div>
<div ng-controller="ControllerTwo">{{Service.getNumber()}} was chosen!</div>
JS
function ControllerOne($scope, Service) {
$scope.setNumber = Service.setNumber;
}
function ControllerTwo($scope, Service) {
$scope.Service = Service;
}
Demo Fidlle

Resources