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
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
)
}
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'];
}
Most helpful comment
The actual cordova plugin seems to be working correctly. It's just access through IonicNative that fails.