I have a problem with data binding in TextField via ngModel
I have model class
export class Product {
name: string
description: string
imageUrl: string
}
View:
<GridLayout backgroundColor="red">
<!--
This part is for logged users
-->
<StackLayout
[id]="container"
[visibility]="isLogged ? 'visible' : 'collapse'">
<Label text="Add product" textWrap="true"></Label>
<TextField
hint="product name"
[(ngModel)]="product.name">
</TextField>
<TextField
hint="product desc"
[(ngModel)]="product.description">
</TextField>
<Button text="Zrób zdjęcie produktu" (tap)="didTapTakePhoto()">
</Button>
<Button text="Wyślij na serwer" (tap)="didTapSendProduct()">
</Button>
<Image #photo></Image>
</StackLayout>
<!--
This part is for not logged users
-->
<StackLayout [visibility]="isLogged ? 'collapse' : 'visible'">
<Label text="Musisz się zalogować!" textWrap="true"></Label>
</StackLayout>
</GridLayout>
and Controller:
import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from "@angular/core"
import * as Firebase from "nativescript-plugin-firebase"
import * as camera from "nativescript-camera";
import { Image } from "ui/image";
import { ImageAsset } from "image-asset"
import { ImageSource } from "image-source"
import { Product } from "../../shared"
@Component({
selector: "AddProductComponent",
templateUrl: "tabs/addProduct/addProduct.html"
})
export class AddProductComponent implements OnInit, OnDestroy {
@ViewChild("photo") photoRef: ElementRef
filePath: string
isLogged: boolean = true
product: Product
listener = {
onAuthStateChanged: function(data) {
this.isLogged = data.loggedIn
},
thisArg: this
}
constructor() {
this.product = new Product()
this.product.name = "Name"
this.product.description = "Desc"
}
ngOnInit(): void {
Firebase.addAuthStateListener(this.listener)
camera.requestPermissions()
}
ngOnDestroy(): void {
Firebase.removeAuthStateListener(this.listener)
}
didTapTakePhoto() {
// init the file-system module
var fs = require("file-system");
// grab a reference to the app folder
var appPath = fs.knownFolders.currentApp().path;
// determine the path to a file in the app/res folder
this.filePath = appPath + "/cached_product_photo.png";
camera.takePicture()
.then((imageAsset) => {
let photo = <Image>this.photoRef.nativeElement
photo.src = imageAsset
let photoSrc = new ImageSource()
photoSrc.fromAsset(imageAsset).then(image => {
console.log("Result: " + image)
image.saveToFile(this.filePath, "png")
})
})
.catch((err) => {
console.log("Error -> " + err.message)
});
}
didTapSendProduct() {
console.log(this.product.name)
console.log(this.product.description)
}
focusDescription() {
console.log(this.product.name)
}
//TODO: move to separate file/import some more professional uuid generator?/
// find any other way to distinguish betweeen photos
getUUID() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1)
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4()
+ s4() + s4()
}
}
When I run my app on iOS device
- textfields are empty (it shouldn't because of my implementation in
constructor()
) when I tap on send button a function
didTapSendProduct()
prints:CONSOLE LOG file:///app/tabs/addProduct/addProduct.component.js:51:20: Name
CONSOLE LOG file:///app/tabs/addProduct/addProduct.component.js:52:20: Desc
no matter what is set in textfields
Note that I have set NativeScriptFormsModule
in my imports:
import { NgModule, NgModuleFactoryLoader } from "@angular/core";
import { NativeScriptFormsModule } from "nativescript-angular/forms";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { NSModuleFactoryLoader } from "nativescript-angular/router";
import { AppComponent } from "./app.component";
import { AppRoutingModule } from "./app-routing.module";
@NgModule({
bootstrap: [
AppComponent
],
imports: [
NativeScriptModule,
AppRoutingModule,
NativeScriptFormsModule
],
declarations: [
AppComponent
],
providers: [
{ provide: NgModuleFactoryLoader, useClass: NSModuleFactoryLoader }
]
})
export class AppModule { }