I am trying to write up a button to display in ionic based on some condition that I want to evaluate in a service. I need to let the service know who called it. So I want to send a parameter to the service. But I see that whatever parameter I pass from my template html, the variable is not visible in the service. Sample code below.
angular.module('starter', ['ionic'])
.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();
}
});
})
.service('testService', function TestService() {
return {
testFunc: function(param) {
console.log("Hello"); //This prints correctly
console.log(param); //This prints as undefined
if (param == 1) return false;
else
return true;
}
}
})
.controller('testController', ['testService',
function(testService) {
console.log("Hello world");
testService.testFunc();
}
])
<!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="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
</head>
<body ng-app="starter" ng-controller="testController">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Blank Starter</h1>
</ion-header-bar>
<ion-content>
<button class="button button-full button-positive icon ion-thumbsup" ng-if="testService.testFunc(10)"> Test</button>
</ion-content>
</ion-pane>
</body>
</html>
Has anyone come across this situation and what is the way to get it working?
Thanks,
Srini
You made two mistakes or missunderstood how to use a service in your html code.
Inside your controller you already call a service function with testService.testFunc(). And because you don't pass a parameter here you wan't receive some paramter in your service.
.controller('testController', ['testService', function(testService) {
console.log("Hello world");
testService.testFunc();
}])
In your html code the following line calls the function testService.testFunc(10). The problem is, your $scope doesn't know such a function. The result will be ng-if="undefined". Your service will be never called.
<button ng-if="testService.testFunc(10)"> Test</button>
So, there are two easy solution get this works.
You can add the service to your $scope with
.controller('testController', function($scope, testService) {
console.log("Hello world");
$scope.testService = testService;
})
or you define a new $scope function inside your controller and call the service inside this function.
$scope.myFunc = function(param){
return testService.testFunc(param);
}
and
<button ng-if="myFunc(10)"> Test</button>
Try
.controller('testController', ['$scope', 'testService',
function($scope, testService) {
console.log("Hello world");
$scope.testService = testService;
}
])
Related
I just started a blank new Ionic project, and I'm going crazy trying to figure out what is wrong with my $stateProvider setup.
My routes.js:
angular.module('starter.routes', [])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/Login',
templateUrl: 'templates/Login.html',
controller: 'loginCtrl'
});
$urlRouterProvider.otherwise('/Login');
});
My app.js:
angular.module('starter', ['ionic', 'starter.routes', 'ui.router'])
.run(function($ionicPlatform, $state, $timeout) {
$ionicPlatform.ready(function() {
console.log("platform ready");
$state.go('login');
// 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.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
});
My 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 rel="manifest" href="manifest.json">
<!-- un-comment this code to enable service worker
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')
.then(() => console.log('service worker installed'))
.catch(err => console.log('Error', err));
}
</script>-->
<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/routes.js"></script>
<script src="js/controllers/login-ctrl.js"></script>
</head>
<body ng-app="starter">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Blank Starter</h1>
</ion-header-bar>
<ion-content>
</ion-content>
</ion-pane>
</body>
</html>
I've already worked on complex ionic apps, and started many on my own, and never had a problem like this, in my app.js, the $state.go('login'); won't work. EVER.
I tried to put that command inside a timeout, or a function but nothing happened, I'm guessing there is something wrong with my declaration of the $stateProvider but I really can't figure out what that could be.. I also tried to copy and pasterino whole sections of working code from other projects...
I really need help!! Thank you!
I am trying to make something like this <[Plunker][1]>
But when i try this exact code in my ionic application i get nothing on the screen.
I have already asked this question couple of time but nobody was able to helped me till now.
If you know some other alternative or some tutorial or link please post it.
NOTE i am exactly copying my ionic project code into plunker so that you can better understand it but it might not work in plunker.
Please help me if you can.
<[MY Plunker][2]>
[1]: http://plnkr.co/edit/H5n7SM?p=preview
[2]: https://plnkr.co/edit/fJTaer?p=preview
index.html
<!DOCTYPE html>
<html data-ng-app="starter">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link rel="manifest" href="manifest.json">
<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">
-->
<script src="cordova.js"></script>
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="js/angular-ui-router.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-cordova/0.1.27-alpha/ng-cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/homeController.js"></script>
<script src="js/secondController.js"></script>
</head>
<body>
<ion-pane>
<ion-content>
<div id="wrapper" ui-view></div>
</ion-content>
</ion-pane>
</body>
</html>
app.js
var app = angular.module('starter', ['ionic','ngCordova', 'ui.router'])
app.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);
}
ionic.Platform.fullScreen();
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
app.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('index', {
url: "",
templateUrl: "home.html",
controller: "homeController"
})
.state('second', {
url: "/second",
templateUrl: "second.html",
controller: "secondController"
})
});
home.html
<div style="width:100px;height: 50px;background-color: blue">home</div>
<button ui-sref="second">click</button>
second.html
<div style="width:100px;height: 50px;background-color: green">second</div>
<button ui-sref="index">click</button>
homeController.js
app.controller('homeController', function($scope,$ionicPlatform,$state) {
});
secondController.js
app.controller('secondController', function($scope,$ionicPlatform,$state) {
});
I have a simple list of items and want to have a button in the header that shows and hides a delete button next to each list item. My header and content are made up of separate views.
After much reading, it seems a controller is attached to a view rather than a state, so I need to have a separate controller for each view (one controller for the header and one controller for the content). As I can't share variables between controllers, what is the best way to have a button in one view (header.html) show/hide buttons in a list in a different view (content.html)?
My HTML is below:
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">
-->
<!--For users deploying their apps to Windows 8.1 or Android Gingerbread, platformOverrided.js
will inject platform-specific code from the /merges folder -->
<script src="js/platformOverrides.js"></script>
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="Scripts/angular-resource.min.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>
<script src="js/services.js"></script>
</head>
<body ng-app="starter">
<ion-view view-title="Playlists">
<div ui-view="header"></div>
<div ui-view="content"></div>
</ion-view>
</body>
</html>
header.html
<ion-header-bar class="bar-positive">
<div class="buttons">
<button class="button button-icon icon ion-ios-minus-outline"
ng-click="data.showDelete = !data.showDelete"></button>
</div>
<h1 class="title">my test app</h1>
</ion-header-bar>
content.html
<ion-content class="has-header has-footer" overflow-scroll="true">
<ion-list show-delete="data.showDelete">
<ion-item ng-repeat="movie in movies" href="#/home/{{movie.id}}">
{{movie.title}}
<ion-delete-button class="ion-minus-circled"
ng-click="onItemDelete(movie)">
</ion-delete-button>
<ion-option-button class="button-assertive" ui-sref="editMovie({id:movie.id})">Edit</ion-option-button>
</ion-item>
</ion-list>
</ion-content>
and my js is below.....
app.js
angular.module('starter', ['ionic', 'ngResource', 'starter.controllers', 'starter.services'])
.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 (cordova.platformId === "ios" && window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.config(function ($stateProvider, $urlRouterProvider) {
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
views: {
'header': {
templateUrl: 'templates/header.html',
controller: 'headerCtrl'
},
'content': {
templateUrl: 'templates/content.html',
controller: 'contentCtrl'
},
'footer': {
templateUrl: 'templates/footer.html'
}
}
});
});
controllers.js
angular.module('starter.controllers', [])
.controller('headerCtrl', function ($scope) {
$scope.showDelete = function () {
$scope.data.showDelete = !$scope.data.showDelete;
};
})
.controller('contentCtrl', function ($scope, $state, $stateParams, Movie) {
// populate list withg all items from database
$scope.movies = Movie.query();
// handle delete button click
$scope.onItemDelete = function (movie) {
$scope.movies.splice($scope.movies.indexOf(movie), 1);
movie.$delete();
$scope.data.showDelete = false;
};
});
You actually can share variables between controllers, by using what Angular calls a "service".
AngularJS: How can I pass variables between controllers?
I want my ionic project to take a screenshot and store it in camera roll.
currently the button is not able to take any screenshot. I am testing the app on an android device.
I am using this plugin: https://github.com/gitawego/cordova-screenshot
index.html
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="js/ng-cordova.min.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<ion-view>
<ion-content>
<button class="button" ng-click="$cordovaScreenshot.capture()">screenshot</button>
</ion-content>
</ion-view>
</body>
</html>
app.js
angular.module('starter', ['ionic','ngCordova'])
.service('$cordovaScreenshot', ['$q', function($q) {
return {
capture: function(filename, extension, quality) {
filename = filename || 'pic';
extension = extension || 'jpg';
quality = quality || '100';
var defer = $q.defer();
navigator.screenshot.save(function(error, res) {
if (error) {
console.error(error);
defer.reject(error);
} else {
console.log('screenshot saved in: ', res.filePath);
defer.resolve(res.filePath);
}
}, extension, quality, filename);
return defer.promise;
}
};
}]);
As a follow-up on my first comment. I think you need a controller between the view (HTML) and your Angular service. A HTML view can't directly communicate with a service, so we need a intermediate controller.
Something along the lines of:
angular.module('starter', ['ionic','ngCordova'])
.controller('myController', ['$cordovaScreenshot', function($cordovaScreenshot) {
$scope.captureScreenshot = function() {
$cordovaScreenshot.capture('filename', 'png', 100).then(function(result) {
// do something with result
}, function(error) {
// do something with error
});
};
}]);
As you can see, we're using dependency injection to inject the $cordovaScreenshot service.
And your view will trigger the captureScreenshot method:
<ion-content ng-controller="myController">
<button class="button" ng-click="captureScreenshot()">screenshot</button>
</ion-content>
Notice the ng-controller and a change in the ng-click method.
The problem was rectified.
The code can be found at
https://github.com/manik1596/coredovaScreenshotShare
I am working on a hybrid ionic app.
I want to get the device id of a android device. I installed cordova plugin, included cordova.min.js file.
I tried by this code, still not displaying anything.
Is there any other way to get device id?
angular.module('starter', ['ionic','ngCordova'])
.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.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.controller('DeviceController', function($ionicPlatform, $scope, $cordovaDevice) {
$ionicPlatform.ready(function() {
$scope.$apply(function() {
var device = $cordovaDevice.getDevice();
$scope.manufacturer = device.manufacturer;
$scope.model = device.model;
$scope.platform = device.platform;
$scope.uuid = device.uuid;
});
});
})
<!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>
<script src="js/ng-cordova.min.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>
</head>
<body ng-app="starter" ng-controller="DeviceController">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Device Information</h1>
</ion-header-bar>
<ion-content>
<div class="item item-text-wrap">
<ul class="list">
<li class="item">
Manufacturer : {{manufacturer}}
</li>
<li class="item">
Model : {{model}}
</li>
<li class="item">
Platform : {{platform}}
</li>
<li class="item">
UUID : {{uuid}}
</li>
</ul>
</div>
</ion-content>
</ion-pane>
</body>
</html>
Provided that you have installed the device plugin, just do window.device.uuid (after you've received the device ready event).
EDIT
Looking again at your code, you don't need the platform ready in the controller and I am not sure if it's going to fire like that. Also why do you call apply in there? How about this:
.controller('DeviceController', function () {
alert(window.device.uuid);
});
you can add below plugin in your project UniqueDeviceID
and add below line in ondevice ready
window.plugins.uniqueDeviceID.get(success, fail);
add success and failure function in your code
function success(){
alert(uuid);
}
function fail(error){
alert("error " + error);
}
Point to note here is ng-cordova.js internally calls the methods and API's od native cordova so it is very important to install the cordova plugins separately even after you install the ng-cordova.js. Then i initialized the device in app.module.
$ionicPlatform.ready(function() {
$scope.deviceInformation = ionic.Platform.device();
});
and i called the method in my intro controller
$scope.getDeviceInfo = function() {
alert($scope.deviceInformation.uuid);
}
Or go through http://ngcordova.com/docs/plugins/device/ will help you..
I got it, The code is perfecr, nothing wrong in that, even the plugin is installed properly. The problem was ng-cordova.min.js. I just downloaded the newest version of ng-cordova.min.js. And its working perfectly.
Thank you everyone.
This might help others.