cordova plugin is not ready - angularjs

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

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>

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>

ng-animate not firing event (ng-enter)

I have the following angularjs application which loads content from Instagram, however, on page load I would like to fade the loaded content in with a smooth transition.
For some reason ng-animate doesn't seem to be firing the ng-enter event. so I can add a CSS animation. Is there something wrong?
HTML
<section ng-controller="ShowImages as images" class="page {{ loadedClass }}" >
<div ng-view>
......
</div>
JS
(function(){
//Place your own Instagram client_id below. Go to https://instagram.com/developer/clients/manage/ and register your app to get a client ID
var client_id = '83aaab0bddea42adb694b689ad169fb1';
//To get your user ID go to http://jelled.com/instagram/lookup-user-id and enter your Instagram user name to get your user ID
var user_id = '179735937';
var app = angular.module('instafeed', ['ngAnimate']);
app.filter('getFirstCommentFrom',function(){
return function(arr, user){
for(var i=0;i<arr.length;i++)
{
if(arr[i].from.username==user)
return arr[i].text;
}
return '';
}
})
app.factory("InstagramAPI", ['$http', function($http) {
return {
fetchPhotos: function(callback){
var endpoint = "https://api.instagram.com/v1/users/self/media/liked/";
endpoint += "?access_token=179735937.83aaab0.e44fe9abccb5415290bfc0765edd45ad";
endpoint += "&callback=JSON_CALLBACK";
$http.jsonp(endpoint).success(function(response){
callback(response.data);
});
}
}
}]);
app.controller('ShowImages', function($scope, InstagramAPI){
$scope.layout = 'grid';
$scope.data = {};
$scope.pics = [];
$scope.$on('$viewContentLoaded', function(){
$scope.loadedClass = 'page-feed';
});
InstagramAPI.fetchPhotos(function(data){
$scope.pics = data;
console.log(data)
});
});
})();
I also link to these in the HTML:
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular/angular-route.js"></script>
<script src="bower_components/angular/angular-animate.js"></script>
What am I doing wrong?
See here:
http://machinas.com/wip/machinas/instagramfeed/
Do u ve included the css file right??
I think u don't need this:
$scope.$on('$viewContentLoaded', function(){
$scope.loadedClass = 'page-feed';
});
The ng-enter is active when u set the value of the var that u use inside the ng-repeat
look at this http://codepen.io/shprink/pen/Ariyc

Trying to integrate Phonegap Connection API with 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

Working with two modules in AngularJS

I have two modules with different operations and I tried to work with them as shown below.
<div id="viewBodyDiv" ng-app="xhr">
<div ng-controller="xhrCtrl">
<button ng-click="callAction()">Click</button>
{{sample}}
</div>
</div>
<div id="viewBodyDiv2" ng-app="xhr2">
<div ng-controller="xhr2Ctrl">
<button ng-click="alertMessage()">Click</button>
</div>
</div>
The JS is shown below.
angular.module('xhr', []).controller('xhrCtrl', function ($http, $scope, $window) {
$scope.sample = "sadf";
$scope.callAction = function () {
$http({
method: 'GET',
url: 'Angular/GetData',
params: {
api_key: 'abc'
}
}).then(function (obj) { //I get a text result that I display near the button
$scope.sample = obj.data;
});
};
});
angular.module('xhr2', []).controller('xhr2Ctrl', ['$window','$scope',
function ($window,$scope) {
$scope.alertMessage = function () {
$window.alert("xhr2Ctrl clicked");
};
}]);
When I click on the viewBodyDiv I am getting the desired output but when I click on viewBodyDiv2 the alert message is not getting displayed.
I am new to AngularJS and please let me know what I am doing wrong or what it the procedure to work with two different Modules in Angular.
Thank you.
add this code to the bottom of your JavaScript
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('viewBodyDiv2'),['xhr2']);
});
Hope this helps.
As per the AngularJS documentation:
https://docs.angularjs.org/api/ng/directive/ngApp
Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application.
However, if you still want to do it this way, you have to use angular.boostrap() manually to achieve this. Here is a good tutorial on this:
http://www.simplygoodcode.com/2014/04/angularjs-getting-around-ngapp-limitations-with-ngmodule/
So you need to bootstrap the module to have multiple angular apps on the same page.
You can also inject one of the modules into another.
var xhrModule = angular.module("xhr", ["xhr2"]);
Following is a sample code for bootstrapping the module.
<html>
<head>
<script src="angular.min.js"></script>
</head>
<body>
<div id="viewBodyDiv" ng-app="xhr">
<div ng-controller="xhrCtrl">
<button ng-click="callAction()">Click</button>
{{sample}}
</div>
</div>
<div id="viewBodyDiv2" ng-app="xhr2">
<div ng-controller="xhr2Ctrl">
<button ng-click="alertMessage()">Click</button>
</div>
</div>
<script>
var xhrModule = angular.module("xhr", []);
xhrModule.controller('xhrCtrl', function ($http, $scope, $window) {
$scope.sample = "sadf";
$scope.callAction = function () {
$http({
method: 'GET',
url: 'Angular/GetData',
params: {
api_key: 'abc'
}
}).then(function (obj) { //I get a text result that I display near the button
$scope.sample = obj.data;
});
};
});
var xhr2Module = angular.module("xhr2", [])
xhr2Module.controller('xhr2Ctrl', ['$window','$scope',
function ($window,$scope) {
$scope.alertMessage = function () {
$window.alert("xhr2Ctrl clicked");
};
}]);
angular.bootstrap(document.getElementById("viewBodyDiv2"),['xhr2']);
</script>

Resources