NativeScriptException - setImageBitmap


#1

Hi Guys,

I am new to nativescript, and however, I’m currently following RPS Tracking Project created by Alex Ziskin.

I’ve been doing so well until I get the exception below which happens when I click Add button to Modal dialog, it crashes when this (showAddItemModal() function) is called instead of showing the Modal dialog with form…see the attached file regarding the error:

System.err: com.tns.NativeScriptException:
System.err: Calling js method onStart failed
System.err: Error: java.lang.Exception: Failed resolving method setImageBitmap on class org.nativescript.widgets.ImageView…

I have pasted codes below for the Modal and the component that use the Modal.

//angular imports
import { Component, OnInit, ViewContainerRef } from "@angular/core";

//nativescript imports
import { Page } from 'ui/page';
import { ModalDialogParams, ModalDialogOptions } from "nativescript-angular/directives/dialogs";
//import { ModalDialogService, ModalDialogParams, ModalDialogOptions } from "nativescript-angular/modal-dialog";
import { ItemEventData, ListView } from 'ui/list-view';
import { ItemTypePickerModalComponent } from "../shared/item-type-picker-modal.component";

//app imports
import { ItemTypeEnum } from '../../shared/static-data';
import { PTDomain } from '../../typings/domain';
import INewItem = PTDomain.INewItem;

import IUser = PTDomain.IUser;

@Component({
    moduleId: module.id,
    selector: 'add-item-modal',
    templateUrl: 'add-item-modal.component.html',
    styleUrls: ['add-item-modal.component.css']
})
export class AddItemModalComponent implements OnInit {
    public prompt: string;

    public formFieldGridCols = '90, *, 90';
    public newItem: INewItem;

    public get btnDoneEnabled() {
        return this.newItem.title.length > 0;
    }

    constructor(
        private params: ModalDialogParams,
        //private modalService: ModalDialogService,
        private vcRef: ViewContainerRef) { }

    public tapCancel() {
        this.params.closeCallback(null);
    }

    public tapDone() {
        this.params.closeCallback(this.newItem);
    }

    ngOnInit() {
       this.prompt = "Add",// this.params.context.promptMsg;
        this.newItem = {
            title: 'Hello',
            description: 'Testing...',
            type: ItemTypeEnum.PBI
        };
    }

    public textViewFieldHeight(value: string): number {
        if (value) {
            let lineHeight = 20;
            let numlines = Math.ceil(value.length / 36);
            let newHeight = ((numlines < 2 ? 2 : numlines) * lineHeight) + 10;
            return newHeight < 150 ? newHeight : 150;
        }
        else {
            return 40;
        }
    }

    /*public showTypeModal() {
        const options: ModalDialogOptions = {
            context: { itemTitle: this.newItem.title, promptMsg: "Select item type" },
            fullscreen: true,
            viewContainerRef: this.vcRef
        };

        this.modalService.showModal(ItemTypePickerModalComponent, options).then((res: ItemTypeEnum) => {
            if (res) {
                this.newItem.type = res;
            }
        });
    }*/
}

<GridLayout class="modal-wrapper " rows="50, *">

    <StackLayout row="0" class="pt-item-detail-header bold">
        <GridLayout columns="*, 50">
            <Label col="0" [text]="newItem.title" textWrap="true" class="pt-item-detail-header-title"></Label>
            <GridLayout col="1" class="modal-close-wrapper" (tap)="tapCancel()">
                <Label text="X"></Label>
            </GridLayout>

        </GridLayout>
    </StackLayout>

    <StackLayout row="1">

        <ScrollView>
            <StackLayout>

                <Label [text]="prompt" class="form-group-label"></Label>

                <StackLayout class="form-group">
                    <StackLayout class="input-field input-field-border">
                        <TextView hint="Enter item title..." [(ngModel)]="newItem.title" [height]="textViewFieldHeight(newItem.title)" class="input"></TextView>
                    </StackLayout>

                    <StackLayout class="input-field">
                        <TextView hint="Enter item description..." [(ngModel)]="newItem.description" [height]="textViewFieldHeight(newItem.description)"
                            class="input"></TextView>
                    </StackLayout>
                </StackLayout>


                <StackLayout class="form-group">
                    <StackLayout #itemTypeRow class="input-field">
                        <GridLayout rows="40" [columns]="formFieldGridCols" (tap)="showTypeModal()">

                            <Label col="0" text="Type" class="input form-field-col"></Label>


                            <StackLayout col="1" #itemTypeName orientation="horizontal" class="form-field-col right">
                                <Image [src]="newItem.type" class="input-img"></Image>
                                <Label [text]="newItem.type" class="input"></Label>
                            </StackLayout>

                            <GridLayout col="2" class="icon-arrow-wrapper">
                              <!--<Image src="res://icon_arrow_forward" class="icon-arrow"></Image>-->
                            </GridLayout>
                        </GridLayout>
                    </StackLayout>
                </StackLayout>


                <StackLayout class="btn-item-add-wrapper">
                    <Button text="Done" (tap)="tapDone()" class="btn-item-add" [class.enabled]="btnDoneEnabled" [isEnabled]="btnDoneEnabled"></Button>
                </StackLayout>

            </StackLayout>
        </ScrollView>

    </StackLayout>

</GridLayout>

import { Component, OnInit, AfterViewInit, ViewChild, ViewContainerRef, ChangeDetectorRef } from '@angular/core';

import { RadSideDrawerComponent, SideDrawerType } from 'nativescript-pro-ui/sidedrawer/angular';
import { SideDrawerLocation, RadSideDrawer } from 'nativescript-pro-ui/sidedrawer';
import {ModalDialogService,ModalDialogOptions} from 'nativescript-angular/directives/dialogs';

import { BacklogService } from '../services';
import { AddItemModalComponent } from "./shared/add-item-modal.component";
import { PTDomain } from '../typings/domain';
import INewItem = PTDomain.INewItem;


@Component({
    moduleId: module.id,
    selector: 'pt-backlog',
    templateUrl: 'pt-backlog.component.html',
    styleUrls: ['pt-backlog.component.css']
})
export class PTBacklogComponent implements AfterViewInit, OnInit {

    private _drawer: RadSideDrawer;
    @ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;

    public selectedViewIndex: number;
    public myTitleProperty: string = "My Backlog";

    constructor(
       private backlogService: BacklogService,
        private modalService: ModalDialogService,
        private vcRef: ViewContainerRef,
        private _changeDetectionRef: ChangeDetectorRef
    ) {

        this.selectedViewIndex = 1;
    }

    ngOnInit() { }

    public ngAfterViewInit() {
        this._drawer = this.drawerComponent.sideDrawer;
        this._drawer.drawerLocation = SideDrawerLocation.Right;
        this._changeDetectionRef.detectChanges();
    }

    public showSlideout() {
        this._drawer.showDrawer();
    }

    public selectFilteredView(itemFilterIndex: number, pageTitle: string) {
        this.selectedViewIndex = itemFilterIndex;
    }

    public showAddItemModal() {
        const options: ModalDialogOptions = {
            viewContainerRef: this.vcRef,
            moduleRef: null,
            context: { promptMsg: "Add item" },
            fullscreen: true

        };
        console.log('1');
        this.modalService.showModal(AddItemModalComponent, options).then((newItem: INewItem) => {
            console.log('2');
            if (newItem != null) {
                console.log('3');
                //  this.backlogService.addNewPTItem(newItem, null);
            }
        });
    }

    public logoutTap() {
        alert('LOGOUT');
    }


    /*public onDoubleTap() {
        alert('double tap');
    }
    public onLongPress() {
        alert('long press');
    }
    public onPan() {
        alert('pan');
    }*/

}

<!--<ActionBar title="Backlog">
    <ActionItem (tap)="showSlideout($event)">
        <StackLayout class="navbar_image_wrapper">
            <Label text="MENU"></Label>
        </StackLayout>
    </ActionItem>
</ActionBar>


    <RadSideDrawer tkToggleNavButton>
    <StackLayout tkDrawerContent class="sideStackLayout">
        <Button text="LOGOUT" (tap)="logoutTap()" padding="10" style="horizontal-align: center"></Button>
        
        <StackLayout class="sideTitleStackLayout">
            <Label text="Navigation Menu"></Label>
        </StackLayout>
        <StackLayout class="sideStackLayout">
            <Label text="Primary" class="sideLabel sideLightGrayLabel"></Label>
            <Label text="Social" class="sideLabel"></Label>
            <Label text="Promotions" class="sideLabel"></Label>
            <Label text="Labels" class="sideLabel sideLightGrayLabel"></Label>
            <Label text="Important" class="sideLabel"></Label>
            <Label text="Starred" class="sideLabel"></Label>
            <Label text="Sent Mail" class="sideLabel"></Label>
            <Label text="Drafts" class="sideLabel"></Label>
        </StackLayout>
        <Label text="Close Drawer" color="lightgray" padding="10" style="horizontal-align: center" (tap)="onCloseDrawerTap()"></Label>
    </StackLayout>
    <StackLayout tkMainContent>
        <pt-item-list></pt-item-list>
        <Label [text]="mainContentText" textWrap="true" class="drawerContentText"></Label>
        <Button text="OPEN DRAWER" (tap)="openDrawer()" class="drawerContentButton"></Button>
    </StackLayout>
</RadSideDrawer>-->


<ActionBar [title]="myTitleProperty">
    <ActionItem (tap)="showSlideout($event)" ios.position="right">
        <StackLayout class="navbar_image_wrapper" ios:horizontalAlignment="right">
            <Label text="MENU"></Label>
        </StackLayout>
    </ActionItem>
</ActionBar>

<RadSideDrawer>
    <StackLayout tkDrawerContent>
        <GridLayout class="side-drawer-panel" rows="auto, *, 100">
            <StackLayout row="0">
                <Label text="LOGO HERE"></Label>
            </StackLayout>

            <StackLayout row="1">
                <Button (tap)="selectFilteredView(0,'MY ITEMS')" [class]="selectedViewIndex === 0 ? 'slide-out-btn-selected':'slide-out-btn'"
                    text="MY ITEMS">
                </Button>

                <Button (tap)="selectFilteredView(1,'OPEN ITEMS')" [class]="selectedViewIndex === 1 ? 'slide-out-btn-selected':'slide-out-btn'"
                    text="OPEN ITEMS">
                </Button>

                <Button (tap)="selectFilteredView(2,'FINISHED ITEMS')" [class]="selectedViewIndex === 2 ? 'slide-out-btn-selected':'slide-out-btn'"
                    text="FINISHED ITEMS">
                </Button>
            </StackLayout>

            <StackLayout row="2">
                <Button text="LOGOUT" (tap)="logoutTap()" class="slide-out-btn"></Button>
            </StackLayout>
        </GridLayout>
    </StackLayout>

    <StackLayout tkMainContent>
        <!-- <pt-item-list></pt-item-list> -->
        <GridLayout class="backlog-container" rows="*, 60">

            <GridLayout row="0" class="list-container">
                <pt-item-list></pt-item-list>
                <!-- <pt-item></pt-item> -->
            </GridLayout>

            <StackLayout row="1" class="btn-add-wrapper">
                <Button text="Add" class="btn-add" (tap)="showAddItemModal()"></Button>
            </StackLayout>

        </GridLayout>
    </StackLayout>
</RadSideDrawer>



<!-- <pt-item></pt-item> -->![NativeScriptExption|644x500](upload://xAOENOspk2hJA1lBYmqbYxqP2X7.PNG)

#2

I guess this line is causing you the issue, its an invalid image. I believe newItem.type refers to a plan string, not a valid image. If you are trying to assign a image from android resources add res:// prefix to path.


#3

Hi Manojdcoder,

Thank you so much for your help, it works as expected now.