danielsogl / awesome-cordova-plugins

Native features for mobile apps built with Cordova/PhoneGap and open web technologies. Complete with TypeScript support.
https://danielsogl.gitbook.io/awesome-cordova-plugins/
Other
2.41k stars 2.42k forks source link

`photoLibrary.getLibrary()` returns undefined when using IonicNative #2785

Closed mixuala closed 3 years ago

mixuala commented 6 years ago

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: const photolib = self.photoLibrary.getLibrary() returns undefined when using IonicNative, but the cordova plugin works fine.

tested with "@ionic-native/photo-library": "^5.0.0-beta.21",

Expected behavior: should get an observable

Steps to reproduce:

ionic start photolib blank --type=angular
[...]
npm run build
ionic cordova plugin add cordova-plugin-photo-library --variable 
 PHOTO_LIBRARY_USAGE_DESCRIPTION="To choose photos"
// upgrade plugin cordova-plugin-add-swift-support 
cordova plugin rm cordova-plugin-add-swift-support --force
cordova plugin add cordova-plugin-add-swift-support

npm install --save @ionic-native/photo-library@beta

// add Native plugin and method below

ionic cordova prepare ios

add method to home.page.ts

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  constructor(private photoLibrary: PhotoLibrary) { }

  scan_PhotoLibrary():Promise<Observable<LibraryItem[]>> {
    const self = this;
    return self.photoLibrary.requestAuthorization()
    .then( ()=>{
        const photolib = self.photoLibrary.getLibrary();
        if (!photolib){
          console.warn("IonicNative PhotoLibrary: not available with this Device")
        }
        return Promise.resolve(photolib);
    }) 
  }
}

Related code:

insert any relevant code here

Other information:

[Error] ERROR – Error: Uncaught (in promise): TypeError: undefined is not an object (evaluating 'photolib.subscribe')
http://localhost:8080/home-home-module.js:115:21
onInvoke@http://localhost:8080/vendor.js:34941:39
run@http://localhost:8080/polyfills.js:2460:49
http://localhost:8080/polyfills.js:3194:37
onInvokeTask@http://localhost:8080/vendor.js:34932:43
runTask@http://localhost:8080/polyfills.js:2510:57
drainMicroTaskQueue@http://localhost:8080/polyfills.js:2917:42
promiseReactionJob@[native code]
Error: Uncaught (in promise): TypeError: undefined is not an object (evaluating 'photolib.subscribe')
http://localhost:8080/home-home-module.js:115:21
onInvoke@http://localhost:8080/vendor.js:34941:39
run@http://localhost:8080/polyfills.js:2460:49
http://localhost:8080/polyfills.js:3194:37
onInvokeTask@http://localhost:8080/vendor.js:34932:43
runTask@http://localhost:8080/polyfills.js:2510:57
drainMicroTaskQueue@http://localhost:8080/polyfills.js:2917:42
promiseReactionJob@[native code]
    defaultErrorLogger (vendor.js:32794)
    handleError (vendor.js:32840)
    next (vendor.js:35432:140)
    (anonymous function) (vendor.js:34672)
    __tryOrUnsub (vendor.js:79377)
    next (vendor.js:79315)
    _next (vendor.js:79259)
    next (vendor.js:79236)
    next (vendor.js:79002)
    emit (vendor.js:34656)
    run (polyfills.js:2460)
    onHandleError (vendor.js:34963)
    runGuarded (polyfills.js:2476)
    _loop_1 (polyfills.js:2999)
    microtaskDrainDone (polyfills.js:3008)
    drainMicroTaskQueue (polyfills.js:2924)
    promiseReactionJob

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

Ionic:

   ionic (Ionic CLI)             : 4.2.1 (/Users/michael/.nvm/versions/node/v8.9.4/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.0.0-beta.13
   @angular-devkit/build-angular : 0.8.6
   @angular-devkit/schematics    : 0.8.6
   @angular/cli                  : 6.2.6
   @ionic/angular-toolkit        : 1.0.0

Cordova:

   cordova (Cordova CLI) : 8.0.0
   Cordova Platforms     : ios 4.5.5
   Cordova Plugins       : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 2.2.0, (and 7 other plugins)

System:

   ios-deploy : 2.0.0
   NodeJS     : v8.9.4 (/Users/michael/.nvm/versions/node/v8.9.4/bin/node)
   npm        : 6.4.1
   OS         : macOS High Sierra
   Xcode      : Xcode 10.0 Build version 10A255
mixuala commented 6 years ago

The actual cordova plugin seems to be working correctly. It's just access through IonicNative that fails.

  cordovaScan(){
    // this.platform.ready()
    const photolib = cordova.plugins['photoLibrary'];
    photolib.getLibrary( 
      (chunk)=>{
        chunk.library.forEach( (libraryItem)=> {
          console.log(libraryItem.id, libraryItem);
        })
        if (chunk.isLastChunk)
          console.log("DONE")
      },
      (err)=>console.log(err),
      options
    )
  }
mixuala commented 5 years ago

IonicNative: PhotoLibrary.getLibrary() has the wrong interface.

IonicNative: PhotoLibrary.getLibrary : (options?: GetLibraryOptions)=>Observable<LibraryItem[]> Cordova Plugin: PhotoLibrary.getLibrary : (success, error, options)=>void

I wrote this method to bridge the gap:

/**
 * IonicNative.PhotoLibrary.getLibrary does not match CordovaPlugin.PhotoLibrary.getLibrary
 *    IonicNative: PhotoLibrary.getLibrary = (options?: GetLibraryOptions)=>Observable<LibraryItem[]>;
 * but `cordova-plugin-photo-library` expects:
 *    Cordova: PhotoLibrary.getLibrary = (success, error, options)=>void
 */
function patch_IonicNativePhotoLibrary(photoLibrary:IonicNativePhotoLibrary):void {
  // force typescript type check to match cordova getLibrary()
  let native_getLibrary:(success:any, error:any, options:GetLibraryOptions)=>void = photoLibrary.getLibrary;
  let done:Subscription;

  if (!photoLibrary['getLibrary_0']) {
    native_getLibrary = photoLibrary.getLibrary;
    photoLibrary['getLibrary_0'] = native_getLibrary;
  }

  const resp$ = new Subject<LibraryItem[]>();

  const callbacks = {
    success: (resp:{isLastChunk:boolean, library:LibraryItem[]})=>{
      resp$.next(resp.library);
      if (resp.isLastChunk) {
        resp$.complete();
        done.unsubscribe();
      }
    }, 
    error: (err)=>{
      resp$.error(err);
      resp$.complete();
      done.unsubscribe();
    }
  };
  photoLibrary['getLibrary_patched'] = (options:GetLibraryOptions): Observable<LibraryItem[]> => {
    done = photoLibrary['getLibrary_0'](callbacks.success, callbacks.error, options).subscribe();
    return resp$.asObservable();
  }
  photoLibrary.getLibrary = photoLibrary['getLibrary_patched'];
}
github-actions[bot] commented 3 years ago

There has been no recent activity and this issue has been marked inactive.