If i create a simple project:
ionic start MyApp
And add the ImagePicker plugin:
ionic plugin add https://github.com/wymsee/cordova-imagePicker.git -save
And simply copy this example www folder into the project and do:
ionic platform add android
ionic build android
ionic run android
Everything is working fine. I can pick multiple images as intended without getting any errors.
So far so good. Now i tried to include that into my project so i added the ImagePicker plugin. Now this is my plugin list:
ionic plugin ls
com.synconset.imagepicker 1.0.6 "ImagePicker"
cordova-plugin-camera 1.1.0 "Camera"
cordova-plugin-device 1.0.0 "Device"
cordova-plugin-dialogs 1.1.0 "Notification"
cordova-plugin-splashscreen 2.0.0 "Splashscreen"
cordova-plugin-statusbar 1.0.0 "StatusBar"
cordova-plugin-vibration 1.1.0 "Vibration"
cordova-plugin-whitelist 1.0.0 "Whitelist"
I created a new module:
angular.module('App.ImageSelect', [])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider.state('app.imageSelect', {
url: "/products/prints/pola/imageSelect",
views: {
'menuContent': {
templateUrl: "modules/products/prints/pola/imageSelect/imageSelect.html",
controller: 'ImageSelectController'
}
}
});
})
.controller('ImageSelectController', function ($scope, $cordovaImagePicker) {
$scope.images = [];
$scope.selectImages = function () {
$cordovaImagePicker.getPictures(
function (results) {
for (var i = 0; i < results.length; i++) {
console.log('Image URI: ' + results[i]);
$scope.images.push(results[i]);
}
if (!$scope.$$phase) {
$scope.$apply();
}
},
function (error) {
console.log('Error: ' + error);
}
);
};
});
As you can see it is EXACTLY the SAME controller which i copied from here which worked on the simple test project.
For any suspect reason this is NOT working. I always get the error:
TypeError: Cannot read property 'getPictures' of undefined
So what's the point of that? Im using EXACT the same code in both projects. In one everything is working and in the other nothing is working. I tried all the examples described here but its always the same.
I checked your project and your index.html is missing cordova.js . So none of your plugins are getting loaded or initialized.
Just add the below line in you index.html below where you load ng-cordova.js.
<script src="cordova.js"></script>
On you example your are injecting $cordovaCamera, however the iconic uses $cordovaImagePicker. Also , in your example your using the object imagePicker from the window object. I don't the window object is what you want.
Try injecting the correct dependency $cordovaImagePicker and use the method $cordovaImagePicker.getPictures from it instead.
Related
I was installed cordova-plugin-media in ionic v1 . But media is not define by the app when I running it in the browser .
ionic.bundle.js:26794 ReferenceError: Media is not defined
at ChildScope.$scope.playPodcast (controllers.js:1405)
at fn (eval at compile (ionic.bundle.js:27638), <anonymous>:4:232)
at ionic.bundle.js:65427
at ChildScope.$eval (ionic.bundle.js:30395)
at ChildScope.$apply (ionic.bundle.js:30495)
at HTMLElement.<anonymous> (ionic.bundle.js:65426)
at defaultHandlerWrapper (ionic.bundle.js:16787)
at HTMLElement.eventHandler (ionic.bundle.js:16775)
at triggerMouseEvent (ionic.bundle.js:2953)
at tapClick (ionic.bundle.js:2942)
and this is my code
$scope.playPodcast = function($audioId) {
new Media("http://www.viaviweb.in/envato/cc/online_mp3_app_demo/uploads/40655_Overboard.mp3").play();
}
Just a quick search to that plugin's github page shows the way to use that method.
Specifically if you want to play a media file, this is the correct way to use it.
function playAudio(url) {
// Play the audio file at url
var my_media = new Media(url,
// success callback
function () { console.log("playAudio():Audio Success"); },
// error callback
function (err) { console.log("playAudio():Audio Error: " + err); }
);
// Play audio
my_media.play();
// Pause after 10 seconds
setTimeout(function () {
my_media.pause();
}, 10000);
}
Ok, depending on how you have the script file injected, you need to call it one of two ways:
If the media plugin is being loaded as a script file that is in your index.html by itself and it attaches itself to the global namespace, then add the following to your app.js:
angular.module('Media', [])
.factory('Media', function () {
return window.Media;
});
Later, in your app.js module definition, add the following:
angular.module('myApp',
[
'ionic',
'Media'
])
.run(
[
'ionicReady',
'Media',
function (
ionicReady,
Media,
) {
//Media initialization code here
}
This allows angular to use its Dependency Injection to ensure "Media" gets initialized in your main module. You'll have to import it to your other modules if you want to use it somewhere else in your application.
If you're using NgCordova, which provides angular wrappers for common Cordova plugins, then you'd import it the same way you'd import any other AngularJS library. There's sample code for the media plugin here.
I'm trying to include typical javascript library(JSZip) in to my angularjs application.
At first i have added included JSZip library in to my application and then added script reference to my index page.
Next i have created a simple object of JSZip in one of my module and trying to create zip. but all of sudden, i am getting compilation error in typescript while building my application in VS2015(visual studio), saying that "Cannot find name JSZip".
How to load non angular dependency in angular application. i have spent a complete day. i didn't find any clue.
i have tried multiple ways to get the dependency dynamically and also tried oclazyload to load JSZip dependency ..but not helps.
var zip = new JSZip(); <=== this is where the problem is..
zip.file("File1", atob(response.Data));
zip.file("File2", atob(response.Data));
zip.generateAsync({ type: "blob" })
.then(function (content) {
// saveAs is from FileSaver.js
saveAs(content, "example.zip");
});
Inject non-angular JS libraries
Include the JS file into your HTML file
<script src="http://stuk.github.io/jszip/dist/jszip.js"></script>
In your module angular add constant 'jszip' for exemple
var app = angular.module('myApp', [])
.constant('jszip', window.JSZip)
.run(function($rootScope) {
$rootScope.JSZip = window.JSZip;
})
Inject 'jszip' in your controller, and you will solve your problem
app.controller('myCtrl', function($scope, 'jszip') {
var zip = new jszip();
...
});
For the downloading part (saveAs function), include FileSaver.js into your HTML file
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.js"></script>
In your controller for exemple
$scope.exportZip = function(){
var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
zip.generateAsync({type:"blob"})
.then(function(content) {
saveAs(content, "example.zip");
});
};
I am extremely new to the world of mobile development and I am working with ionic framework.
All I am trying to do is to display a toast message to the user by following this tutorial and so far I am just going crazy trying to implement it.
The error I get is as following
Cannot read property 'toast' of undefined
I have installed cordova
I have installed the Toast plugin
inside my index.html I have added the script of ng-cordova.min.js
<script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
Do i need to add the Toast.js file in index.html too? If yes then that does not help either and leads to another error.
This is my controller
.controller('UsersController', ['$scope', '$http', '$cordovaToast', function ($scope, $http, $cordovaToast) {
$scope.showToast = function() {
$cordovaToast
.show("Here's a message", 'short', 'center')
.then(function(success) {
console.log('Success');
}, function (error) {
console.log('Error');
});
};
}
]);
What am i missing here?
I will really appreciate any help.
UPDATE
After making changes, suggested by #Del, the following error appears
ionic.bundle.js:25642 Error: [$injector:unpr] Unknown provider: $cordovaToastProvider <- $cordovaToast <- UsersController
http://errors.angularjs.org/1.4.3/$injector/unpr?p0=%24cordovaToastProvider%20%3C-%20%24cordovaToast%20%3C-%20UsersController
at ionic.bundle.js:13380
at ionic.bundle.js:17574
at Object.getService [as get] (ionic.bundle.js:17721)
at ionic.bundle.js:17579
at getService (ionic.bundle.js:17721)
at invoke (ionic.bundle.js:17753)
at Object.instantiate (ionic.bundle.js:17770)
at ionic.bundle.js:22326
at self.appendViewElement (ionic.bundle.js:56883)
at Object.switcher.render (ionic.bundle.js:54995)
If the plugin is correctly installed, I have used it without using $cordovaToast
.controller('UsersController', ['$scope', '$http', function ($scope, $http) {
$scope.showToast = function() {
window.plugins.toast
.show("Here's a message", 'short', 'center')
.then(function(success) {
console.log('Success');
}, function (error) {
console.log('Error');
});
};
}
]);
You dont have to add the ng-cordova or toast.js.
If you add the plugin (ionic plugin add ...), remove the platform, add again, and build, it should work
You are trying to run $cordovaToast on browser. It will not work because it is a native plugin. Please use it on a real device or emulator.
I am also new in ionic but I have little knowledge about android so then I found the way how to use android functions in ionic means I found the way to create own plugins from here.
so after following steps from the given link I have created an own plugin
you can see it ionic plug # github.
you need to follow simple 4 steps mentioned at git link.
hopefully, it will help you to sort out the same problem.
This error will not go away on the real device as well unless you inject the dependency for $cordovaToast. You may use or may remove $cordovaToast in the controller and it will not affect the working. It is good practice to keep dependencies. The crucial step which is missing in all the responses is to introduce DI for ngCordova in the module to which UsersControllers belongs.
The example highlighted by JSalaat has this controller
foodShop.controller('cartController', function($scope, cartFactory,
$cordovaToast)
and the foodshop module has injected ngCordova.
var foodShop = angular.module('foodShop',
['ionic','firebase','ngCordova'])
As the plug-in belong to ngCordova it does not need to be introduced separately in the controller. This explains why there is no error in that application.
in your case try the app instance creation could look like
var app = angular.module('app', ['ionic','ngCordova'])
if not you will continue to have the Unknown provider: $cordovaToastProvider error
For the record: For Ionic v2/v3
Install dependencies
Include it in ionic project
How to use it.
1. Install dependencies
Within CLI run below commands:
$ ionic cordova plugin add cordova-plugin-x-toast
$ npm install --save #ionic-native/toast
2. Include it in ionic project
1.Add below to app.module.ts
import { Toast } from '#ionic-native/toast';
....and to #NgModule section providers:[ HERE,]
2.Each page where you want to use Toast you need to add:
import { Toast } from '#ionic-native/toast';
....also add to constructor
constructor(private toast: Toast, ...){}
...now you can use it as below example:
this.toast.show('message', 'duration', 'position').subscribe();
...or sending message to console:
this.toast.show('message', 'duration', 'position').subscribe(
toast=>{
console.log(toast);
}
);
My app is looking good, thanks to Ionic. All the core info is there and I'm just adding the frills - email, sharing, media (one of the functions is a metronome) and so on.
I can't get any plugins to work.
I've had success with a previous Ionic app but the plugins were all called from within
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
}
}
and indeed the Statusbar plugin seems to working fine and it is called from within there.
I'm using the Side Menu starter with tabs built in btw.
My issue, I suppose, is that I've three controller files.
main_ctrls.js - for the main app
menu_ctrls.js - for the menu pages like feedback and email, analytics
extras_ctrls.js - for the "extra" section with the metronome and so on.
I've put 'ngCordova' as a dependency in each module and called the plugin from within the controller with the ready function. Here is the email controller.
angular.module('menu.controllers', ['ngCordova'])
.controller('FeedCtrl', function($ionicPlatform, $scope, $cordovaEmailComposer) {
$ionicPlatform.ready(function() {
$cordovaEmailComposer.isAvailable().then(function() {
// is available
alert('Email is available');
}, function () {
// not available
alert('Email is NOT available');
});
var email = {
to: 'max#mustermann.de',
cc: 'erika#mustermann.de',
bcc: ['john#doe.com', 'jane#doe.com'],
attachments: [
'file://img/logo.png',
'res://icon.png',
'base64:icon.png//iVBORw0KGgoAAAANSUhEUg...',
'file://README.pdf'
],
subject: 'Cordova Icons',
body: 'How are you? Nice greetings from Leipzig',
isHtml: true
};
$cordovaEmailComposer.open(email).then(null, function () {
alert('Email discarded.');
});
})
});
I'm testing it on Android (Nexus 4 with Android 5.1) with Chrome inspect and I just get an error saying "Cannot read property 'isAvailable' of undefined". Needless to say, the alerts don't pop up.
This happens with all plugins called from within controllers in this way.
What am I doing wrong?
It seems like you are invoking the plugins before the cordova device ready is fired. In my angularjs application I have done the following.
1. Removed ng-app from html and did manual bootstrap through script
2. Added cordova.js file to the dependency. ( As the last dependency. After ng-cordova js)
3. Placed the cordova.js in the same folder as that of the index.html. (No explanation for why. From any other location, simply it was not getting added. May be something specific pertaining to cordova.)
4. Added the following script to the index.html
<script type="text/javascript" language="text/javascript">
$(document).ready(function() {
document.addEventListener("deviceready", onDeviceReady, false);
});
onDeviceReady = function() {
alert("hello!");
angular.element(document).ready(function() {
angular.bootstrap(document, ["main"]);
});
};
</script>
Here "main" is my main angularjs module. This ensures that the app is loaded only after the device ready event is fired by cordova and all cordova related functions are available. Specific to ionic I donot have anycode. May be the portion where ionic bootstraps the app can be put instead of angular.bootstrap.
My assumptions: you have added the plugins to your cordova project through the command
cordova plugin add <plugin-location>
index.html ng-cordova include are okay if you can use ngCrdova plugins in app.js, I think ng-cordova is bad injected across angular dependencies. Try this:
app.js
controllers.js
adding ng-cordova to project involves adjusting the module definition files like:
app.js
angular.module('startapp', ['ionic','ngCordova','startapp.controllers'])
controllers.js
angular.module('startapp.controllers', [])
.controller('AppCtrl', function($scope,$cordovaEmailComposer) {
var email = {
to: 'max#mustermann.de',
cc: 'erika#mustermann.de',
bcc: ['john#doe.com', 'jane#doe.com'],
attachments: [
'file://img/logo.png',
'res://icon.png',
'base64:icon.png//iVBORw0KGgoAAAANSUhEUg...',
'file://README.pdf'
],
subject: 'Cordova Icons',
body: 'How are you? Nice greetings from Leipzig',
isHtml: true
};
$cordovaEmailComposer.open(email).then(null, function () {
// user cancelled email
});
})
Only include ngCordova in app.js app definition.
I work on a Ionic project (AngularJS + Apache Cordova aka Phonegap).
The first code's lines of my project are 4 months, and yesterday, the application nolonger works on emulators and real devices, but still work into chrome window. So I suppose my angular code is correct, but I don't know where is the issue, and I didn't know how to handle it.
At the beginning I coded directly in my www folder, and I test it either into chrome with devtools and device emulation, or in chrome with the Apache Ripple extension, and at times I install it into my real device (Nexus S).
I recently installed grunt and bower into my project for common tasks, and I decided to reorganize my project folder.
Then now, I code into a src folder, and :
before testing in chrome, I run grunt 'dev' tasks witch creates a www folder and includes a dedicated index.html linked to scr/ js, html,css and other res files.
before testing in emulator or real device, I run grunt 'prod' tasks witch creates a www folder and includes build or copy all the needed files to the the app (app.min.css, app.min.js, templates, fonts and media files, icon).
Both of it work fine in chrome, but when I build (via either cordova-cli or phonegap build) and install the app on emulator or real device, I get the splash screen and then, a permanent white screen.
I tried to debug it with the help of weinre I and note that the js console doesn't catch any thrown error.
But I placed some console.log and it appears that the routing is broken.
angular.module('app').run() is executed, but the first controller that is AppCtrl is never executed.
Here is my module code (important parts for this post) :
(function(){
angular.module('app', [
'ionic',
'ngCordova',
'app.auth',
'app.model',
'app.action',
// 'app.test',
])
.run(['$ionicPlatform',
function($ionicPlatform) {
alert("app.run() runs ...");
}])
.config(['$stateProvider','$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
var tmplt_dir = 'modules/app/tmplt';
var tmplt = function(viewName){
return tmplt_dir + '/' + viewName + '.html' ;
};
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: tmplt('app') ,
controller: 'AppCtrl'
})
.state('app.main', {
url: "/main",
abstract: false,
views: {
"menuContent" : {
templateUrl: tmplt('main') ,
controller: 'MainCtrl'
}
}
})
.state('app.main.home', {
url: "/home",
views: {
'homeTabContent' :{
templateUrl: tmplt('home') ,
controller: 'HomeCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/main/home');
}])
.controller('AppCtrl', [ '$rootScope', '$cordovaToast', '$window',
function($rootScope, $cordovaToast, $window) {
alert('AppCtrl runs...');
$rootScope.notImplementedException = function(){
var message = "Bientôt disponible.";
try {
$cordovaToast.showShortCenter(message);
} catch(e){
alert(message);
}
};
$rootScope.browserOpen = function(href){
var ref = $window.open(href, '_system', 'location=yes');
};
}])
.controller('MainCtrl', [ function() {
alert('MainCtrl runs...');
}])
.controller('HomeCtrl', [ '$rootScope','$auth', '$app',
function($rootScope, $auth, $app) {
alert('HomeCtrl runs...');
if (!$auth.checkLogin()) {
$auth.authError();
}
$rootScope.appName = $app.name;
}])
})();
The only alerts that appears is :
app.run() runs ...
So, the alerts that don't appear are :
AppCtrl runs...
MainCtrl runs...
HomeCtrl runs...
Remember that in chrome, all works perfectly !
This issue is really baffling and I've already lost a few hours to track it, unsuccessfully.
Any idea ?
I solved my problem.
In fact, I wrote an httpRequestInterceptor factory which check if an url have to be signed to use my Rest API.
A recent change of the structure of my project folder causing this factory returning sometimes a wrong result, then signing some local url and causing bad routing, then whitescreen.
Run ionic build ios
Run ionic emulate ios
Open Safari-> Develop -> Simulator -> index.html (for your app)
Check console for errors (if any)
Press reload (usually on top left) and monitor the console tab for errors.
If you are using Parse (or such), make sure you initialize these before using them in your code. This is a common reason for white screens.
This state does not exists
$urlRouterProvider.otherwise('/app/main/home');
I think it should be
$urlRouterProvider.otherwise('/home');
We use gapdebug to debug our ionic applications. You can also debug realtime on your device if its plugged in to the computer and its a very good debugger for any emulator.
For me i solved it by replacing this
$stateProvider.state('nameOfState', {
templateUrl: '/templates/nameOfTemplate.html',
})
With this
$stateProvider.state('nameOfState', {
templateUrl: './templates/nameOfTemplate.html',
})
Try to add a "." before the full URL in "templateUrl". Worked for me!