nstudio / nativescript-camera-plus

MIT License
79 stars 50 forks source link

All functions undefined #123

Open srokatonie opened 4 years ago

srokatonie commented 4 years ago

I have copied the demo-ng (it wouldn't start after cloning the repo for some reason) and tried to run.

Install plugin:

tns plugin add @nstudio/nativescript-camera-plus
npm install
tns run ion #after connecting a device

Component:

import { Component, NgZone, OnDestroy, OnInit } from '@angular/core';
import { ImageAsset } from '@nativescript/core/image-asset';
import { ImageSource } from '@nativescript/core/image-source';
import { CameraPlus } from '@nstudio/nativescript-camera-plus';

@Component({
  selector: 'ns-progress-pictures',
  moduleId: module.id,
  templateUrl: './progress-pictures.component.html',
})
export class ProgressPicturesComponent implements OnInit, OnDestroy {
  private cam: CameraPlus;
  public imageSource: ImageSource;

  constructor(private zone: NgZone) { }

  ngOnInit(): void { }

  ngOnDestroy() { }

  public camLoaded(e: any): void {
    console.log('***** cam loaded *****');
    this.cam = e.object as CameraPlus;

    const flashMode = this.cam.getFlashMode();

    // Turn flash on at startup
    if (flashMode === 'off') {
      this.cam.toggleFlash();
    }

    // TEST THE ICONS SHOWING/HIDING
    // this.cameraPlus.showCaptureIcon = true;
    // this.cameraPlus.showFlashIcon = true;
    // this.cameraPlus.showGalleryIcon = false;
    // this.cameraPlus.showToggleIcon = false;
  }

  public imagesSelectedEvent(e: any): void {
    console.log('IMAGES SELECTED EVENT!!!');
    this.loadImage((e.data as ImageAsset[])[0]);
  }

  public photoCapturedEvent(e: any): void {
    console.log('PHOTO CAPTURED EVENT!!!');
    this.loadImage(e.data as ImageAsset);
  }

  public toggleCameraEvent(e: any): void {
    console.log('camera toggled');
  }

  public recordDemoVideo(): void {
    try {
      console.log(`*** start recording ***`);
      this.cam.record();
    } catch (err) {
      console.log(err);
    }
  }

  public stopRecordingDemoVideo(): void {
    try {
      console.log(`*** stop recording ***`);
      this.cam.stop();
      console.log(`*** after this.cam.stop() ***`);
    } catch (err) {
      console.log(err);
    }
  }

  public toggleFlashOnCam(): void {
    this.cam.toggleFlash();
  }

  public toggleShowingFlashIcon(): void {
    console.log(`showFlashIcon = ${this.cam.showFlashIcon}`);
    this.cam.showFlashIcon = !this.cam.showFlashIcon;
  }

  public toggleTheCamera(): void {
    this.cam.toggleCamera();
  }

  public openCamPlusLibrary(): void {
    this.cam.chooseFromLibrary();
  }

  public takePicFromCam(): void {
    this.cam.takePicture({ saveToGallery: true });
  }

  private loadImage(imageAsset: ImageAsset): void {
    if (imageAsset) {
      ImageSource.fromAsset(imageAsset).then(
        imgSrc => {
          if (imgSrc) {
            this.zone.run(() => {
              this.imageSource = imgSrc;
            });
          } else {
            this.imageSource = null;
            alert('Image source is bad.');
          }
        },
        err => {
          this.imageSource = null;
          console.log('Error getting image source: ');
          console.error(err);
          alert('Error getting image source from asset');
        }
      );
    } else {
      console.log('Image Asset was null');
      alert('Image Asset was null');
      this.imageSource = null;
    }
  }
}

Html:

<ActionBar title="Cam Test Capture" class="action-bar">
</ActionBar>
<ScrollView>
    <GridLayout rows="250, auto, *">
        <CameraPlus height="250" debug="true" galleryPickerMode="single" showFlashIcon="true" showToggleIcon="true"
         showCaptureIcon="true" showGalleryIcon="true" confirmSaveText="CONFIRM!" confirmRetakeText="RETAKE!" (loaded)="camLoaded($event)"
         (toggleCameraEvent)="toggleCameraEvent($event)" (photoCapturedEvent)="photoCapturedEvent($event)"
         (imagesSelectedEvent)="imagesSelectedEvent($event)">

            <!-- OVERLAY CONTENT -->
            <!-- <GridLayout rows="*, auto, *" columns="*, auto, *">
                <GridLayout colSpan="3" class="bg-overlay"></GridLayout>
                <GridLayout row="1" class="bg-overlay"></GridLayout>
                <GridLayout row="1" col="2" class="bg-overlay"></GridLayout>
                <GridLayout row="2" colSpan="3" class="bg-overlay"></GridLayout>
                <Label row="1" col="1" class="overlay-label" text="📷➕"></Label>
                <Image src="https://d2odgkulk9w7if.cloudfront.net/images/default-source/default-album/nativescript.png" row="1" col="1" stretch="aspectFill"
                    class="overlay" width="20" height="20"></Image>
                <Image src="res://nativescript" row="1" col="1" stretch="aspectFill" class="overlay"></Image>
            </GridLayout> -->

        </CameraPlus>

        <GridLayout row="1" rows="auto, auto" columns="*, auto, *" *ngIf="imageSource">
            <Label columnSpan="3" textWrap="true" text="Captured Image"></Label>
            <Image row="1" col="1" class="preview-image" stretch="none" [src]="imageSource"></Image>
        </GridLayout>

        <GridLayout row="2" rows="auto, auto, auto, auto" columns="*, *">
            <Button text="Record Video" (tap)="recordDemoVideo()" row="0" col="0" class="btn btn-primary"></Button>
            <Button text="Stop Recording" (tap)="stopRecordingDemoVideo()" row="0" col="1" class="btn btn-primary"></Button>
            <Button text="Take Pic" (tap)="takePicFromCam()" row="1" col="0" class="btn btn-primary"></Button>
            <Button text="Toggle Flash" (tap)="toggleFlashOnCam()" row="1" col="1" class="btn btn-primary"></Button>
            <Button text="Toggle Camera" (tap)="toggleTheCamera()" row="2" col="0" class="btn btn-primary"></Button>
            <Button text="Open Library" (tap)="openCamPlusLibrary()" row="2" col="1" class="btn btn-primary"></Button>
        </GridLayout>
    </GridLayout>
</ScrollView>

Console:

NativeScript debugger attached.
CONSOLE LOG file: src/app/pages/progress-pictures/progress-pictures.component.ts:22:16: ***** cam loaded *****
CONSOLE ERROR [native code]: ERROR TypeError: this.cam.getFlashMode is not a function. (In 'this.cam.getFlashMode()', 'this.cam.getFlashMode' is undefined)
CONSOLE ERROR [native code]: ERROR CONTEXT {
"view": {
"def": {
"nodeFlags": 50380801,
"rootNodeFlags": 33554433,
"nodeMatchedQueries": 0,
"flags": 0,
"nodes": [
{
"nodeIndex": 0,
"parent": null,
"renderParent": null,
"bindingIndex": 0,
"outputIndex": 0,
"checkIndex": 0,
"flags": 33554433,
"childFlags": 49152,
"directChildFlags": 49152,
"childMatchedQueries": 0,
"matchedQueries": {},
"matchedQueryIds": 0,
"references": {},
"ngContentIndex": null,
"childCount": 1,
"bindings": [],
"bindingFlags": 0,
"outputs": [],
"element": {
"ns": "",
"name": "ActionBar",
"attrs": [
[
"",
"class",
"action-bar"
],
[
"",
"title",
<\M-b\M^@\M-&>
CONSOLE ERROR [native code]: ERROR TypeError: this.cam.takePicture is not a function. (In 'this.cam.takePicture({ saveToGallery: true })', 'this.cam.takePicture' is undefined)
CONSOLE ERROR [native code]: ERROR CONTEXT {
"view": {
"def": {
"nodeFlags": 50380801,
"rootNodeFlags": 33554433,
"nodeMatchedQueries": 0,
"flags": 0,
"nodes": [
{
"nodeIndex": 0,
"parent": null,
"renderParent": null,
"bindingIndex": 0,
"outputIndex": 0,
"checkIndex": 0,
"flags": 33554433,
"childFlags": 49152,
"directChildFlags": 49152,
"childMatchedQueries": 0,
"matchedQueries": {},
"matchedQueryIds": 0,
"references": {},
"ngContentIndex": null,
"childCount": 1,
"bindings": [],
"bindingFlags": 0,
"outputs": [],
"element": {
"ns": "",
"name": "ActionBar",
"attrs": [
[
"",
"class",
"action-bar"
],
[
"",
"title",
<\M-b\M^@\M-&>

I see the initial screen with 6 buttons, but the console log throws errors about undefined functions.

Any idea what's wrong?

bradmartin commented 4 years ago

Can you log out the e.object and ensure it's the CameraPlus instance?

srokatonie commented 4 years ago

@bradmartin

public camLoaded(e: any): void {
    console.log('***** cam loaded *****');

    console.log(e.object);

    this.cam = e.object as CameraPlus;

    const flashMode = this.cam.getFlashMode();

    // ...

I am getting ProxProxyViewContaineryiew:

CONSOLE LOG file: src/app/pages/progress-pictures/progress-pictures.component.ts:22:16: ***** cam loaded *****
CONSOLE LOG file: src/app/pages/progress-pictures/progress-pictures.component.ts:24:16: ProxyViewContainer(104)
CONSOLE ERROR [native code]: ERROR TypeError: this.cam.getFlashMode is not a function. (In 'this.cam.getFlashMode()', 'this.cam.getFlashMode' is undefined)
CONSOLE ERROR [native code]: ERROR CONTEXT {
"view": {
...
bradmartin commented 4 years ago

k so that does help

CONSOLE LOG file: src/app/pages/progress-pictures/progress-pictures.component.ts:24:16: ProxyViewContainer(104)

is definitely not the CamPlus instance, I forget if the demo does similar, but you need to get the camera instance (which you seem to be aware of that). I think this used to work just fine. Have you registered the element via registerElement in your angular app for this plugin?

bradmartin commented 4 years ago

https://github.com/nstudio/nativescript-camera-plus/blob/master/demo-ng/src/app/app.component.ts#L4

srokatonie commented 4 years ago

Ok, that worked. I've missed registerElement from the demo.

The README could contain a bit more info about the installation:

// iOS setup

// Add to App_Resources/iOS/Info.plist

<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires access to the photo library.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app requires access to the photo library.</string>

// Angular

// Add in AppComponent

import { CameraPlus } from '@nstudio/nativescript-camera-plus';
import { registerElement } from '@nativescript/angula

I don't mind creating a PR for that?

The demo is also not working, getting an error:

$npm run demo.ng.ios
...
../src/camera-plus.ios.ts:1419:5 - error TS2304: Cannot find name 'CGPointMake'.
1419     CGPointMake(50.61, 23.35)
...

I could look at this later as well.

bradmartin commented 4 years ago

PR appreciated for sure, thanks 👍 - as for the demo warning, we might just need to add skipLibCheck:true to the tsconfig for that project since you normally dont scan node_modules for typing warnings.