ionic 2 get ion-input text to refresh - angularjs

I have a page with an ion-input in a FormGroup.
When they go to the page, data is loaded from a server. When the data comes in I want the ion-input to be filled in with the data from the server, which the user can then edit and save.
I cannot get the ion-input to show the data. (it remains blank)
Here is the page:
import { Component,ViewChild } from '#angular/core';
import { Validators, FormBuilder, FormGroup } from "#angular/forms";
import { NavController, App, MenuController, NavParams, AlertController,Content } from 'ionic-angular';
import {DomSanitizer,SafeResourceUrl} from '#angular/platform-browser';
import { TabsPage } from '../tabs/tabs';
// Providers
import { ProjectDetailService } from '../../providers/project-detail-service';
#Component({
selector: 'page-form',
templateUrl: 'form.html',
})
export class FormPage {
#ViewChild(Content) content: Content;
newObject: FormGroup;
object: any = {};
objectKey: string = "";
pageTitle: string = "Create New";
videoURL: SafeResourceUrl;
sanitizer: DomSanitizer;
updating: boolean = false;
constructor( public formBuilder: FormBuilder,
public service: ProjectDetailService,
public navParams: NavParams,
public app: App,
public alertCtrl: AlertController,
sanitizer: DomSanitizer ) {
this.sanitizer = sanitizer;
this.newObject = this.formBuilder.group({
name: this.object.name
});
}
setData()
{
this.newObject.value.name = this.object.name;
//none of these work:
//this.content.resize();
//window.location.reload();
//this.app.getRootNav().setRoot(this.app.getRootNav().getActive().component);
}
ionViewDidLoad()
{
this.objectKey = this.navParams.get('projectKey');
console.log("objectkey="+this.objectKey)
this.service.getProject(this.objectKey).subscribe( ( data: any ) => {
this.object = data;
this.setData();
})
}
This is the html:
<ion-content padding>
<form [formGroup]="newObject" (ngSubmit)="save()">
<ion-item>
<ion-label>Project Name</ion-label>
<ion-input type="text" formControlName="name"></ion-input>
</ion-item>
</form>
</ion-content>

I think FormBuilder is not a two way bindier Instead use a simple two way binding like this
<ion-input type="text" [(ngModel)]="name" formControlName="name"></ion-input>
and access as
this.name = 'something';

Related

Edit Items in a List Using Modal in Ionic 3

I have created an Array and I'm adding items to the array using Modal.
Now i need to edit the item by selecting it from the list.
please help me with the Code.
How to fetch the item to modal and bring back the edited item in the same place in the list
HOME.HTML
<ion-header>
<ion-navbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item *ngFor="let grocery of itemsArray">{{grocery}}</ion-item>
</ion-list>
<button ion-button round (click)="addItem()">Add Item</button>
</ion-content>
HOME.TS
export class HomePage {
public itemsArray = [];
newItem: any;
constructor(public navCtrl: NavController, public modalCtrl: ModalController, public navParams: NavParams) {
}
ionViewDidLoad() {
this.newItem = this.navParams.get('data');
this.itemsArray = [
];
}
public addItem() {
let modalPage = this.modalCtrl.create(ModalPage);
modalPage.onDidDismiss(data => {
this.itemsArray.push(data.name
);
});
modalPage.present();
}
}
MODAL.HTML
<ion-header>
<ion-navbar>
<ion-title>Add Item</ion-title>
<ion-buttons end>
<button ion-button (click)="closeModal()">Close</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-item>
<ion-label>Item</ion-label>
<ion-input type="text" [(ngModel)]="newItem"></ion-input>
</ion-item>
<button ion-button color="secondary" (click)="add()">Add Item</button>
</ion-list>
</ion-content>
MODAL.TS
export class ModalPage {
name:any;
newItem: any;
constructor(public navCtrl: NavController, public viewCtrl: ViewController, public navParams: NavParams) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad ModalPage');
}
public closeModal() {
this.viewCtrl.dismiss();
}
//add() {
// let data = {"name": this.newItem};
// this.viewCtrl.dismiss(data.name)
// }
add() {
let data = {"name": this.newItem};
this.viewCtrl.dismiss(data)
}
}
The code untill now works fine.
I would recommend using alert controller to simplify your code in your use case. If you would need a modal - you can elaborate the code later.
Try this approach:
<ion-header>
<ion-navbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list *ngFor="let grocery of itemsArray; let i = index">
<ion-item (click)="changeItemName(grocery, i)">{{grocery}}</ion-item>
</ion-list>
<button ion-button round (click)="addItem()">Add Item</button>
</ion-content>
Place iterator on the list and capture "index" per item, so that you could pass that value if particular item from the list is clicked together with actual grocery item name.
In your home.ts:
import { Component } from '#angular/core';
import { NavController, NavParams, AlertController, ViewController } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public itemsArray = ["milk", "butter", "bread"];
newItem: any;
constructor(public navCtrl: NavController, public alertCtrl: AlertController, public navParams: NavParams) {
}
public changeItemName(currentName, index) {
let alert = this.alertCtrl.create({
title: 'Change grocery item name:',
message: 'current: "' + currentName + '"',
inputs: [
{
placeholder: 'type in a new name'
}
],
buttons: [
{
text: 'Cancel',
role: 'cancel',
},
{
text: 'Confirm',
handler: data => {
if (data[0].length === 0) {
this.itemsArray[index] = currentName;
} else {
this.itemsArray[index] = data[0];
}
}
}
]
});
alert.present();
};
public addItem() {
let index = this.itemsArray.length;
this.changeItemName("New item", index);
}
}
You can use alert controller to show a small pop-up with input field. In the code you will see that we pass parameters to it and we modify list item name OR we add item to the list if change name method was called by addItem method.
Let me know if this is helpful for you.
Here is a working snippet: https://stackblitz.com/edit/ionic-urbtag

Runtime Error Cannot read property 'element' of undefined in angular 2?

I have created form builder validators that do a validation perfectly but i need get a error message from validators so i have tried some method that i shown below
import { Injectable,Output,Component} from '#angular/core';
import { FormGroup, FormControl} from '#angular/forms';
import{Sharedata} from '../providers/sharedata';
export class NextPayDayValidator1 {
public error: any="Next Pay Date should be greater than todays date";
constructor(public Share:Sharedata){
}
public isValid(control: FormControl): any {
// console.log("false");
let formGroup = control.parent;
var IsValid=true;
var errormessage;
// this.Err="eerere";
if(formGroup) {
console.log("true");
var SelVal_Howpaid=formGroup.get('Frequency').value;
console.log(SelVal_Howpaid);
var today = new Date();
var today_date = today.getDate();
var today_month = today.getMonth();
var today_year = today.getFullYear();
var weekNo = 0;
for (var index = week[0]; index <= week[1]; index++) {
weekNo++;
}
var nextpaydaycontrol=formGroup.get('NextPayDate');
var date_next = new Date( formGroup.get('NextPayDate').value);
var date_nextpaydate = date_next.getDate();
var month_nextpaydate = date_next.getMonth();
var year_nextpaydate = date_next.getFullYear();
console.log("nextpaydaycontrol"+date_next +"date"+date_nextpaydate+"month"+month_nextpaydate+"year"+year_nextpaydate);
if (nextpaydaycontrol.value == "") {
IsValid = false;
errormessage = "* Please select Next Pay Date";
console.log(errormessage);
this.error=errormessage;
alert(this.error);
return{
" * Please select Next Pay Date":true
}
}
}
}
my addleads.html
<ion-item>
<ion-label>Next Pay Date:</ion-label>
<!--<ion-input formControlName="NextPayDate" type="number"></ion-input>-->
<ion-datetime displayFormat="MM/DD/YYYY" formControlName="NextPayDate" (ionChange)="npay()"></ion-datetime>
</ion-item>
<span style="color:red" *ngIf="!RegisterForm3.controls.NextPayDate.valid && (!RegisterForm3.controls.NextPayDate.dirty || submitAttempt)">ddd </span>
<span style="color:red" *ngIf="!RegisterForm3.controls.NextPayDate.valid && RegisterForm3.controls.NextPayDate.hasError('Paymustgreaterthentodaydate') && (!RegisterForm3.controls.NextPayDate.dirty || submitAttempt)"> * Next Payday Must Be Greater Than Today's Date </span>
<span style="color:red" *ngIf="!RegisterForm3.controls.NextPayDate.valid && RegisterForm3.controls.NextPayDate.hasError('Invalid') && (!RegisterForm3.controls.NextPayDate.dirty || submitAttempt)"> * Invalid Next Payday</span>
<hr/>
and my addlead ts
import { Component} from '#angular/core';
import { NavController,Platform } from 'ionic-angular';
import {ViewChild} from '#angular/core';
import {Content} from 'ionic-angular';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import{Sharedata} from '../../providers/sharedata';
import {NextPayDayValidator1} from '../../validators/NextPayDate'
import 'rxjs/add/operator/map';
/*
Generated class for the AddLeads page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
templateUrl: 'add-leads.html'
})
export class AddLeadsPage {
RegisterForm3: FormGroup;
public NextPayDateErrorMsg:any;
loading: any;
constructor(public navCtrl: NavController,platform: Platform,public np:NextPayDayValidator1 ,private datePipe: DatePipe, public formBuilder: FormBuilder, public toastCtrl: ToastController,public loginservice :Loginservice,public sharedata:Sharedata, public loadingCtrl: LoadingController,
public http: Http, public alertCtrl: AlertController) {
this.NextPayDateErrorMsg=this.np.error;
alert(this.NextPayDateErrorMsg)
this.RegisterForm3 = formBuilder.group({
LastPayDate: ['', Validators.required],
NextPayDate:['',np.isValid]//here i invoke my validator
});
}
}
the above code i have create error global variable.if any error occurs assign errormsg to error global variable;if i trying to execute validation validation will fires error messge shown in alert after closing alert me getting a error like
EXCEPTION: Error in ./AddLeadsPage class AddLeadsPage - inline
template:427:65 caused by: Cannot set property 'error' of undefined
any one help me to fix this bugs
You have set a custom validator NextPayDayValidator1 as a component instead of a directive. A component cannot be injected like a provider.
Check here for custom validators.
#Directive({
selector: '[next-pay-valid]',
providers: [{provide: NG_VALIDATORS, useExisting: NextPayDayValidator1, multi: true}]
})
export class NextPayDayValidator1 implements Validator, OnChanges {..}
Or create a provider for NextPayDayValidator1
#Injectable()
export class NextPayDayValidator1 {
public error: any="Next Pay Date should be greater than todays date";
constructor(public Share:Sharedata){
}
public isValid(control: FormControl): any {
// console.log("false");
let formGroup = control.parent;
var IsValid=true;
//....
}
}
and inject in your component constructor.

Refresh sortable when a new item is added to the array

Sortable component only shows initial array elements. When a new value is pushed into array, the sortable does not display it.
Component:
import { Component } from '#angular/core';
#Component({
selector: 'custom-item-template-demo',
templateUrl: './custom-item-template.html'
})
export class CustomItemTemplateDemoComponent {
public itemStringsLeft: any[] = [
'Windstorm',
'Bombasto',
'Magneta',
'Tornado'
];
public addItem() {
this.itemStringsLeft.push("new item");
}
}
Template:
<button type="button" (click)="addItem()">Add</button>
<template #itemTemplate let-item="item" let-index="index"><span>{{index}}: {{item.value}}</span></template>
{{itemStringsLeft.length}}
<pre>{{ itemStringsLeft | json }}</pre>
<bs-sortable
[(ngModel)]="itemStringsLeft"
[itemTemplate]="itemTemplate"
itemClass="sortable-item"
itemActiveClass="sortable-item-active"
placeholderItem="Drag here"
placeholderClass="placeholderStyle"
wrapperClass="sortable-wrapper"
></bs-sortable>
Workaround: Call manually to writeValue of the SortableComponent
import { Component, ViewChild } from '#angular/core';
#Component({
selector: 'custom-item-template-demo',
templateUrl: './custom-item-template.html'
})
export class CustomItemTemplateDemoComponent {
public itemStringsLeft: any[] = [
'Windstorm',
'Bombasto',
'Magneta',
'Tornado'
];
#ViewChild(SortableComponent, {static: false}) sortableComponent: SortableComponent;
public addItem() {
this.itemStringsLeft.push("new item");
this.sortableComponent.writeValue(this.itemStringsLeft);
}
}
Another workaround with re asigning list values:
public addItem() {
this.itemStringsLeft.push("new item");
this.itemStringsLeft = this.itemStringsLeft.slice();
}
should be add import { SortableComponent } from 'ngx-bootstrap';
It will working.
The spread operator worked well for me with this issue:
addItem(){
this.itemStringsLeft = [...this.itemStringsLeft, {name: 'Windstorm', range: 5}];
}

AngularJS Cannot find a differ supporting object '[object Object]' of type 'object' and Parse Query

So when I try to take my data from my parse query and put it in my array I end up with this error Cannot find a differ supporting object '[object Object]' of type 'object'. My Code for the Html and ts file are below. And my model file is also below. Is there a better way to display this data in the list?
Html:
<ion-header>
<ion-navbar>
<ion-title button-right>Trade</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="addTrade()">
<ion-icon name="add"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
<ion-list [virtualScroll]="items">
<ion-item *virtualItem="let item">
{{ item.offering }} {{item.needs}}
</ion-item>
</ion-list>
</ion-content>
and my ts file
import { Component } from '#angular/core';
import { NavController, NavParams, AlertController } from 'ionic-angular';
import { Items} from "../../trade-model";
var Parse = require('parse');
/*
Generated class for the Trade page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
selector: 'page-trade',
templateUrl: 'trade.html'
})
export class TradePage {
searchQuery: string = ''
items: Items ={
offering: [],
needs: []
}
constructor(public navCtrl: NavController, public navParams: NavParams, public alertCtrl: AlertController) {
Parse.initialize('blankedout','unused', "blankedout");
Parse.serverURL = 'blankedout';
}
ionViewWillEnter(){
this.initializeItems()
}
ionViewWillLeave(){
}
initializeItems() {
var this_ref = this
var Trade = Parse.Object.extend("Trade")
var query = new Parse.Query(Trade);
query.find({
success: function(trades) {
for (var i = 0; i < trades.length; i++) {
this_ref.items.offering = trades[i].get("offer")
this_ref.items.needs = trades[i].get("wants")
}
}
});
}
}
This is the template/interface
export interface Items{
offering: string[];
needs: string[];
}
items is an object. Ionic virtualScroll requires an array to be passed in.
Do you mean to do:
<ion-list [virtualScroll]="items.offering">
<ion-item *virtualItem="let item">
{{ item}}
</ion-item>
</ion-list>

Ionic2 and AngularJS2 application using Typescript doesn't find type

I am trying to build an Ionic2 and AngularJS2 application using TypeScript, and I am getting the error: EXCEPTION: No provider for CalEvent!
// File event.ts
export class CalEvent {
name: string;
date: Date;
description: string;
isComplete: boolean;
constructor(n: string, d: Date){
this.name = n;
this.date= d;
}
toString(){
return this.name + ' at ' + this.date;
}
}
/*****************************/
// File event_card_large.ts
import {Component} from 'angular2/core'
import {CalEvent} from '../classes/event.ts';
#Component({
selector: 'event-card-large',
template: '<div style="color: red;">here</div>'
})
export class EventCardLarge{
constructor(public calEvent: CalEvent){}
}
/*****************************/
// File my_page.ts
import {Page} from 'ionic-angular';
import {CalEvent} from '../../classes/event.ts';
import {EventCardLarge} from '../../components/event_card_large.ts';
#Page({
templateUrl: 'build/pages/my_page/my_page.html',
directives:[EventCardLarge]
})
export class MyPage {
public pageName: string;
public testItems: CalEvent[];
selectedItem = 0;
constructor() {
// Test code
this.pageName = 'Test Page 2016-05-17';
this.testItems = [];
let d1 = new Date('2016-05-17');
let ce = new CalEvent('The name', d1);
ce.isComplete = true;
this.testItems.push();
}
}
/*****************************/
// File my_page.html
...
<ion-item *ngFor="#v of testItems; #i = index" >
<event-card-large [calEvent]="v">Loading...</event-card-large>
</ion-item>
...
Thanks for any help.
The problem is you are trying to inject CalEvent in EventCardLarge:
constructor(public calEvent: CalEvent){}
Just declare calEvent as a member of EventCardLarge:
export class EventCardLarge{
calEvent: CalEvent;
constructor(){}
}
It turned out that I needed to make the CalEvent class a "provider", and inject it in the EventCardLarge metadata.
#Component({
selector: 'event-card-large',
template: '<div style="color: red;">here</div>',
providers: [CalEvent]
})

Resources