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);
}
);
Related
I am attempting to upgrade a large angular.js app (1.5.9) to the latest version of Angular.
I am in the process of turning the app into a hybrid AngularJs/Angular app and have reached this step in the guide:
https://angular.io/guide/upgrade#bootstrapping-hybrid-applications
So far I have changed from using gulp to webpack 4 and the app is working the same as before.
The issue I am having is, when I switch from using the ng-app directive in my index.html to bootstrapping in Javascript the app fails to start, throwing this error:
Uncaught Error: [$injector:unpr] Unknown provider: StateServiceProvider <- StateService
This is coming from my app.js file which looks like this:
angular.module('app-engine', [
'app-engine.state',
'app-engine.api',
// other modules
])
.factory('bestInterceptor', bestInterceptor)
// other configs which aren't throwing Unknown provider errors
.run(startUp);
bestInterceptor.$inject = ['StateBootstrappingService'];
function bestInterceptor(StateBootstrappingService) {
return {
request: config => {
if (!StateBootstrappingService.isBestSsoOn()) {
config.headers['x-impersonated-user'] = StateBootstrappingService.getUserName();
}
return config;
}
};
}
startUp.$inject = ['$rootScope', '$state', '$timeout', 'StateService']
function startUp($rootScope, $state, $timeout, StateService) {
// start up code
}
There is a separate app.modules.js file, which defines the other modules in the app.
Including:
angular.module('app-engine.state', ['rx', 'app-engine.api']);
The service which is mentioned in the Unknown provider error looks like this:
(function() {
'use strict';
angular
.module('app-engine.state')
.factory('StateService', StateService);
StateService.$inject = [
'$state',
'$log',
'rx',
// a few other services that exist in the app
];
function StateService(
// all the above in $inject
) {
// service code
}
})();
As the guide instructs, I am removing the ng-app="app-engine" from my index.html and adding it into the JavaScript instead. I've added it at the bottom on my app.modules.js file.
angular.bootstrap(document.body, ['app-engine']);
After this change is when the Unknown provider error is thrown. I have confirmed the source is my startUp function in app.js. I have tried including all the modules in the app in the 'app-engine' requires array, which did not change anything. It's interesting that the bestInterceptor function is not throwing any errors, despite also using a service (The StateBootstrappingService is being set up in the same way as the StateService).
Is there anything obvious I am doing wrong? Or anyone have any ideas how to solve this?
Try this:
angular.element(document).ready(function () {
angular.bootstrap(document.body, ['app-engine'])
})
For me this was necessary because the other sub components (providers and services) had not yet been added to the module yet. Running the it on "document.ready()" gives those items an opportunity to attach before trying to manually bootstrap (because they cannot be added later when manually bootstrapping)
I don't love the use of document.ready() so I'm still looking for a more offical way to do this
I am trying to implement AdMob to an app. I have installed cordova-plugin-admob and am trying to load $cordovaAdMob into controller as stated in official documentation Cordova AdMob, but I get unknown provider error. I figured that maybe it doesn't work in browser, but same happens if I run it on mobile.
If needed, here is controller code, but it's AdMob empty since I haven't passed even that first issue.
.controller('newsCtrl', ['$state', 'Injection', '$scope', '$http', 'SERVER', 'thumbSERVER', '$cordovaAdMob',
function ($state, Injection, $scope, $http, SERVER, thumbSERVER, $cordovaAdMob) {
Injection.ResourceFactory.getResource($http, SERVER, 'news')
.then(function (response) {
$scope.news = response.data.news;
}, function (error) {
});
$scope.thumbnailPath = thumbSERVER;
}])
EDIT:
cordova.js is added automatically when creating new platform (I have installed android) and it is referenced in index.html by default. If I inject it, I get error
Error: [$injector:nomod] Module 'ngCordova' is not available!
I have ended up using the AdMob from this link, and following the "Quick start" section and conforming it to my needs, instead of "Installation" section which is obvieusly missing something
I'm trying to use this plugin: csZbar
The problem is if i follow what is written in the github repository like this:
var app = angular.module('starter', ['ionic'])
app.controller("MainCtrl", function($scope){
$scope.newTask = function() {
cloudSky.ZBar.scan({}, function(succcess){
console.log(success);
}, function(error){
console.log(error);
})
};
});
the error log says:
ReferenceError: cloudSky is not defined
The csZbar is already included in the plugins folder.
I'm totally new to Ionic.
My problem was that I tried to run the app on desktop browser before run on ios.
It doesn't work if you simply run ionic serve, you must run it on ios itself.
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.
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.