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.
Related
Background: I have a gui I'm putting together for an application I've been working on. The app loads its last state from a YAML file, and is supposed to save that state to the YAML file when the app closes. I'm using the following event listener...
// Handle close event
window.addEventListener('beforeunload', function(event) {
if(doc) {
// This line gives error: "Uncaught ReferenceError: main is not defined"
doc.project_notes.text = main.summernoteText;
fs.writeFile('../resources/project.yml', yaml.safeDump(doc), function (error) {
if (error) {
throw error
}
});
}
console.log("Bye...");
});
angular
.module('inspinia')
.controller('MainCtrl', MainCtrl)
(and in my index.html)
<body ng-controller="MainCtrl as main">
I'm saving all of the states in a global variable called doc. It loads the yml file just fine using the following
function MainCtrl() {
activeProject = LoadActiveProject();
/**
* summernoteText - used for Summernote plugin
*/
this.summernoteText = doc.project_notes.text;
};
My issue is primarily with scope of the angular controller/variables.
First, am I handling this correctly in general?
If this is reasonable, how can I update doc.project_notes.text from my unload function OR link the two variables by reference?
I'm pretty new to Javascript.
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);
}
);
I really like Angular.
Having said that, I want to create a plugin in Angular that can be hosted in other websites - no matter what framework they're using. These frameworks can be Angular and it might be something else.
Surely, the latter it easier. I just add my Angular code and violla. It just works. The former is what I'm having troubles with - websites that do use Angular.
A simple setup created locally failed due to:
WARNING: Tried to load angular more than once.
Any suggestions on how I can overcome this issue ?
It sounds almost like you want to create an angular module that you may register on NPM.
In terms of the error you referenced, you may want to tweak your "loader" script. I have created a few public npm modules that use this format also with webpack to create the scripts. This is what my "loader" script looks like. It allows for script tag, commonJS, and AMD module loading.
import mooAccordionDirective from './mooAccordion.js';
import mooRepeatTranscludeModule from 'moo-utility-repeat-transclude';
(function (root, factory) {
if (typeof module !== 'undefined' && module.exports) {
// CommonJS
if (typeof angular === 'undefined') {
var angular = require('angular');
factory(angular);
module.exports = 'mooAngularAccordion';
} else {
factory(angular);
module.exports = 'mooAngularAccordion';
}
} else if (typeof define === 'function' && define.amd) {
// AMD
define(['angular'], factory);
} else {
// Global Variables
factory(root.angular);
}
}(this, function (angular) {
'use strict';
// create your angular module and do stuff
var moduleName = 'mooAngular.accordion';
var mod = angular.module(moduleName, ['mooAngular.utilityRepeatTransclude']);
mooAccordionDirective(mod);
return moduleName; // the name of your module
}));
For more reference on how I built the entire project using Webpack+AngularJS+ES6 you can view my github page for the moo-angular-accordion project.
For you to use this script it would look like:
(function (root, factory) {
if (typeof module !== 'undefined' && module.exports) {
// CommonJS also this prevents your error you are getting.
if (typeof angular === 'undefined') {
var angular = require('angular');
factory(angular);
module.exports = 'myModuleExportString';
} else {
factory(angular);
module.exports = 'myModuleExportString';
}
} else if (typeof define === 'function' && define.amd) {
// AMD
define(['angular'], factory);
} else {
// Global Variables
factory(root.angular);
}
}(this, function (angular) {
'use strict';
// create your angular module and do stuff
var moduleName = 'myModule';
var mod = angular.module(moduleName, ['otherDepModulesIfNeeded']);
mod.directive(/*... defined here ...*/);
return moduleName; // the name of your module
}));
Breakdown:
You define a IIEF which is called with this and your module function (factory) provided as arguments.
The logic checks to see if angular already exists in the global namespace (and if CommonJS support is available.
If angular exists, use it (so that it isn't defined twice), and pass that angular to your module definition (factory)
If not CommonJS, check AMD
If not AMD, load to root as a global (usable as a Script tag)
EDIT: You can also use Grunt, Gulp, or whatever build system you want to bundle your assets instead of Webpack, however the magical script above makes your module exportable in multiple formats (AMD, Script Tag, CommonJS, etc.).
#Sean Larkin's answer is correct, but for those of you using jspm and typescript, here'e what I did there.
1) Write your App module:
/// <reference path="typings/tsd.d.ts" />
import * as angular from "angular";
import modules from "./Modules"; // a simple exported array
// Create our angular module.
angular.module("module.name", modules);
2) Run this command to build a bundle:
jspm bundle-sfx App - angular app.min.js --globals "{ 'angular': 'angular' }" --minify
3) Now app.min.js is an ES5 module library easy to be loaded in a script tag or even another jspm consumer website.
I am creating a NodeJS app which uses AngularJS for it's front-end. I am Also using RequireJS to load in the JS dependencies and then instantiate the Angular app. Here is what I am trying to do:
Within my HTML file (written in Jade) I include the RequireJS files and then call the RequireJS config using the 'data-main' attribute:
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
script(type="text/javascript" src="/bower_components/requirejs/require.js" data-main="/main.js")
My main.js file looks as follows:
"use strict";
function(require) {
require(['/assets/requiredPathsAndShim.js'], function(requiredPathsAndShim) {
require.config({
maps : {
// Maps
},
paths : requiredPathsAndShim.paths,
shim : {
// Modules and their dependent modules
}
});
angular.bootstrap(document, ['appNameInHere']);
});
})(require);
I have an external file which contains an object with my routes '/assets/requiredPathsAndShim.js' and it looks like follows:
"use strict";
(function(define) {
define([], function() {
return {
paths : {
'angular' : '/bower_components/angular/angular'
}
};
});
})(define);
I will add that my NodeJS/Express app has the 'bower_components' folder set to serve static files and this is working fine.
Whenever I try and instantiate the AngularJS app using the 'angular.bootstrap...' method it tells me Angular is not defined. I can't see why this is happening and haven't been able to figure it out yet. O can't see any problem with my routes to the Angular files. Can anyone see or suggest why this may be happening?
Thanks!
Just managed to crack it! I had to place the 'angular.bootstrap' call in a callback function of the require.config method as the app was trying to call AngularJS before it had been defined.
Hope this helps anyone in the future.
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.