Ionic-native: [iOS] Email Composer undefined is not a function

Created on 29 Jan 2019  Â·  5Comments  Â·  Source: ionic-team/ionic-native

I'm submitting a ... (check one with "x")
[x] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or https://ionicworldwide.herokuapp.com/

Current behavior:

I can't check on ios is the email available. I use code from docs: https://ionicframework.com/docs/native/email-composer

this.emailComposer.isAvailable().then((available: boolean) => { });

Btw - open functionality works perfectly 🚀

Steps to reproduce:

Related code:

[Debug] Ionic Stop Scroll injected! (user-script:1, line 50)
[Log] Angular is running in the development mode. Call enableProdMode() to enable the production mode. (vendor.js, line 58290)
[Log] Ionic Native: deviceready event fired after 965 ms (cordova.js, line 1732)
[Log] OPEN database: _ionicstorage (cordova.js, line 1732)
[Log] new transaction is queued, waiting for openDetails operation to finish (cordova.js, line 1732)
[Log] OPEN database: _ionicstorage - OK (cordova.js, line 1732)
[Log] DB opened: _ionicstorage (cordova.js, line 1732)
[Error] ERROR – Error: Uncaught (in promise): TypeError: undefined is not a function (near '...EmailComposer.getPlugin().isAvailable...')
http://192.168.1.111:8100/vendor.js:82936:62
http://192.168.1.111:8100/vendor.js:82146:25
ZoneAwarePromise@http://192.168.1.111:8100/polyfills.js:3255:37
tryNativePromise@http://192.168.1.111:8100/vendor.js:82145:31
sendFeedback@http://192.168.1.111:8100/community-community-module.js:111:39

callWithDebugContext@http://192.168.1.111:8100/vendor.js:65550:30
dispatchEvent@http://192.168.1.111:8100/vendor.js:61929:36
http://192.168.1.111:8100/vendor.js:74725:48
onInvokeTask@http://192.168.1.111:8100/vendor.js:58751:43
runTask@http://192.168.1.111:8100/polyfills.js:2540:57
invokeTask@http://192.168.1.111:8100/polyfills.js:2843:41
invokeTask@http://192.168.1.111:8100/polyfills.js:4089:20
globalZoneAwareCallback@http://192.168.1.111:8100/polyfills.js:4115:27
Error: Uncaught (in promise): TypeError: undefined is not a function (near '...EmailComposer.getPlugin().isAvailable...')
http://192.168.1.111:8100/vendor.js:82936:62
http://192.168.1.111:8100/vendor.js:82146:25
ZoneAwarePromise@http://192.168.1.111:8100/polyfills.js:3255:37
tryNativePromise@http://192.168.1.111:8100/vendor.js:82145:31
sendFeedback@http://192.168.1.111:8100/community-community-module.js:111:39

Other information:

Ionic info: (run ionic info from a terminal/cmd prompt and paste output below):

Ionic:

   ionic (Ionic CLI)             : 4.9.0 (/usr/local/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.0.0
   @angular-devkit/build-angular : 0.12.3
   @angular-devkit/schematics    : 7.2.3
   @angular/cli                  : 7.2.3
   @ionic/angular-toolkit        : 1.2.2

Cordova:

   cordova (Cordova CLI) : 8.1.2 ([email protected])
   Cordova Platforms     : ios 4.5.5
   Cordova Plugins       : cordova-plugin-ionic-webview 2.3.2, (and 6 other plugins)

System:

   ios-deploy : 1.9.4
   ios-sim    : 7.0.0
   NodeJS     : v10.15.0 (/usr/local/bin/node)
   npm        : 6.4.1
   OS         : macOS Mojave
   Xcode      : Xcode 10.1 Build version 10B61

Most helpful comment

Any workaround guys? I've tried to catch this promises but they return nothing 🤣

All 5 comments

It looks like the wrapper isn't fully implemented.
When I use the permission methods the promise is never returned.

I don't know if this has anything to do with updates in the email-composer.

Same issue here. I also integrated the plugin as described in the docs, like:

this.emailComposer.isAvailable().then((available: boolean) => { });

But the promise is never resolved, but rejected without any exception. Neither a native exception is logged in Xcode. I'm using Ionic 4 with Capacitor, btw. Ionic Native version 5.2.0.

Any workaround guys? I've tried to catch this promises but they return nothing 🤣

I was able to fix this issue by using the cordova-plugin-email-composer directly in combination with the working @ionic-native/android-permissions plugin.

ionic cordova plugin add cordova-plugin-email-composer
ionic cordova plugin add cordova-plugin-android-permissions
npm install @ionic-native/android-permissions --save

Then import Provider for AndroidPermissions and @ionic-native/android-permissions/ngx in your
app.module.ts section of providers

providers: [
        StatusBar,
        SplashScreen,
        ....
        AndroidPermissions
    ],

Then I built a proxy service to use everywhere in the app, like any other service. (What the damn ionic-native plugin should do by house)

import {Injectable} from "@angular/core";
import {Platform} from "@ionic/angular";
import {AndroidPermissions} from "@ionic-native/android-permissions/ngx";

declare var cordova: any;

@Injectable()
export class EmailComposerService {

    constructor(private platform: Platform,
                public androidPermissions: AndroidPermissions
    ) {

    }


    composeEmail(toEmailAddress) {

        this.platform.ready().then(() => {
            if (this.platform.is("cordova")) {
                this.androidPermissions
                    .requestPermission(cordova.plugins.email.permission.GET_ACCOUNTS)
                    .then(() => {
                    this.androidPermissions
                        .hasPermission(cordova.plugins.email.permission.GET_ACCOUNTS)
                        .then((hasPermission: boolean) => {
                        if (hasPermission) {
                            cordova.plugins.email.open({
                                to: toEmailAddress,
                            });
                        } else {
                            console.log("Permission denied!");
                        }
                    });

                }).catch((error: any) => {
                    console.log("Request permision failed");
                    console.dir(error);
                });
            }
        });
    }

}


I still need to test this with using iOS, but it works like a charm on android. It does not even ask for a permission. However I will leave the permission part like that, as it works for me.

It just pops a dialog with Gmail or Native Email to choose from.

I hope it helps!

The ionic plugin is definitly unfinished and will never return a response just return; pretty much like the ionic team itself. LOL . happy coding!

Was this page helpful?
0 / 5 - 0 ratings