2

I am following the instructions for Capacitor Camera APi https://capacitor.ionicframework.com/docs/guides/ionic-framework-app

The plugin works fine when running the application on an android device ionic capacitor run android -l but when serving the app on web I am getting this runtime error:

core.js:15724 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'split' of undefined
TypeError: Cannot read property 'split' of undefined
    at camera.js:62
    at new ZoneAwarePromise (zone.js:910)
    at CameraPluginWeb.push../node_modules/@capacitor/core/dist/esm/web/camera.js.CameraPluginWeb._getCameraPhoto (camera.js:60)
    at CameraPluginWeb.<anonymous> (camera.js:40)
    at step (tslib.es6.js:99)
    at Object.next (tslib.es6.js:80)
    at tslib.es6.js:73
    at new ZoneAwarePromise (zone.js:910)
    at Module.__awaiter (tslib.es6.js:69)
    at HTMLElement.<anonymous> (camera.js:29)
    at resolvePromise (zone.js:831)
    at zone.js:741
    at rejected (tslib.es6.js:71)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)
    at Object.onInvoke (core.js:17299)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:390)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (zone.js:150)
    at zone.js:889
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:17290)

This is my code:

import {Injectable} from '@angular/core';
import {from, Observable} from 'rxjs';
import {CameraOptions, CameraResultType, CameraSource, Plugins} from '@capacitor/core';

const { Camera } = Plugins;

@Injectable()
export class MediaService {
    takePhoto(): Observable<string | void> {

        const options: CameraOptions = {
            quality: 100,
            allowEditing: false,
            source: CameraSource.Camera,
            resultType: CameraResultType.Base64
        };
        return from(Camera.getPhoto(options).then(photo => {
            return 'data:image/png;base64,' + photo.base64String;
        }).catch(err => {
            console.error('Error: ', err);
        }));
    }

}

I also added these in main.ts

import { defineCustomElements } from '@ionic/pwa-elements/loader';

// Call the element loader after the platform has been bootstrapped
defineCustomElements(window);

Is there anything i am doing wrong or this is a bug in Capacitor Camera API

Hassan Al Bourji
  • 185
  • 1
  • 13

2 Answers2

3

The problem is the camera can't be used from http, it needs https. Try running with ionic serve --ssl and update the capacitor.config.json to use the https url

"server": {
  "url": "http://192.your.local.ip:8100"
}
jcesarmobile
  • 51,328
  • 11
  • 132
  • 176
  • Android studio is complaining about this and thus greeting me with a white screen: E/chromium: [ERROR:ssl_client_socket_impl.cc(946)] handshake failed; returned -1, SSL error code 1, net_error -202 – Nikita Fuchs Jan 12 '20 at 22:01
  • Are you using a https url with self signed certificate? – jcesarmobile Jan 12 '20 at 22:02
  • I'm actually just following Ionic's official "first app" tutorial which suffers from this very issue, trying to solve this I stumbled upon a comment from you which I referenced in this issue: https://github.com/ionic-team/ionic-docs/issues/1169 I ran $ionic cap run android -l --ssl --external , I have no clue whether there is more to do. Emulator says it's requesting from "https ://192.168.178.23:8100". – Nikita Fuchs Jan 12 '20 at 22:15
  • Yeah, the —ssl option uses self signed certificates and those won’t work on Capacitor. Also, devApp is a Cordova app, Capacitor apps won’t work there. Just run the same command without ssl param and run from android Studio, that way should use the native plugin, not the web plugin. – jcesarmobile Jan 12 '20 at 22:28
  • Thanks, ran $ionic cap run android -l --external , same old "no camera without ssl" problem: "Cannot read property 'enumerateDevices' of undefined" – Nikita Fuchs Jan 12 '20 at 22:44
  • But are you running from android studio? That can only happen if using the web plugin, not the native plugin (i.e. running on chrome) – jcesarmobile Jan 12 '20 at 23:17
  • I was starting the app from Android Studio. What solved the problem now was removing the url in `server` in capacitor.config.json . That way, when building the app and then starting it from Android Studio, he finally didn't rely on live (re)loading the app from some location and and actually used the files on the android system. Is there an easier way around all this? – Nikita Fuchs Jan 12 '20 at 23:29
  • 1
    That shouldn’t happen, if running from android studio it should use the native plugin, not the web plugin, so not iré wat to tell you. – jcesarmobile Jan 12 '20 at 23:34
  • You can give it a shot, here is the project: https://mega.nz/#!ZNUBAKTA!9muf2XmX4p2VidRgC3YmMueCoggkiRfq3ov9MoW6BOQ and this is the tutorial that gave me the crucial hint (see last step): https://dev.to/aaronksaunders/running-react-with-ionic-capacitor-live-reload-32nn – Nikita Fuchs Jan 12 '20 at 23:38
2

If you are using Ionic With Capacitor then this is for you 1)install pwa element

"@ionic/pwa-elements": "^1.4.1",

2)In your main.ts file add this line

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';


platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.log(err));

 // Call the element loader after the platform has been bootstrapped
 defineCustomElements(window);  // add this line
  • No effect at all – Fernando V Apr 29 '20 at 23:26
  • `defineCustomElements(window)` returns a promise. If you are calling it right before calling `takePhoto()`, you might need to do something more like `defineCustomElements(window).then(()=>{takePhoto()})` – Mike Spear Jul 14 '20 at 01:36