Error: ExpressionChangedAfterItHasBeenCheckedError - ionic-framework

I am trying to set the value of the attendance.studentName using value on ion-input. But I am getting an error.
I want to push the value of the ion-input and ion-select to firebase.
<!-- When I delete the ngModel it works -->
<ion-input disabled="true" value="{{student.name}}" [(ngModel)]="attendance.studentName" > {{student.name}} </ion-input>
<ion-select item-end [ngModel]="attendance.status">
<ion-option value="Present">Present</ion-option>
<ion-option value="Absent">Absent</ion-option>
<ion-option value="Late">Late</ion-option>
</ion-select>
</ion-item>
**EDIT **
I am fetching the value of the input from firebase and i dont want the user to edit it so I disabled it. Then i fetch the input using the ngModel.
Here's my code..
TS
import { Student } from '../../models/students/students.model';
import { Attendance } from '../../models/attendance/attendance.model';
export class CheckAttendancePage {
studentList$: Observable<Student[]>
attendance: Attendance = {
studentName: '',
status: ''
}
constructor(private afDatabase: AngularFireDatabase, private studentsList: StudentListService, private attendanceList: AttendanceListService,
public navCtrl: NavController, public navParams: NavParams) {
this.studentList$ = this.studentsList
.getStudentList()
.snapshotChanges()
.map(
changes => {
return changes.map(c => ({
key: c.payload.key, ...c.payload.val()
}))
}
)
}
addAttendance(attendance: Attendance){
console.log(attendance)
}
HTML

In .ts file need to setup attendance object
attendance:any={'studentName': '', .'status':''}
in constructor you can set this value
this.attendance.studentName = your firbase name
In .html file
<ion-item>
<ion-input disabled="true" [(ngModel)]="attendance.studentName" type="text">
</ion-input>
<ion-select item-end [(ngModel)]="attendance.status">
<ion-option value="Present">Present</ion-option>
<ion-option value="Absent">Absent</ion-option>
<ion-option value="Late">Late</ion-option>
</ion-select>
</ion-item>
Setting value of attendance.studentName in constructor
constructor(private firebaseDB: AngularFireDatabase){
this.firabase= this.firebaseDB.list('/users');// your route
this.attendance.studentName= this.firabase.name;
}
Setting value of attendance.studentName in user define method suppose its name Dbcall
First of all inject public navCtrl: NavController in constructor
Dbcall(){
this.attendance.studentName= database student value
this.navCtrl.setRoot(this.navCtrl.getActive().component);
}

Related

ion-select, ion-input and retrive its value on second page

I am getting the number values from the ion-select and input a number in the ion-input. How can I display the selected value and the input value from the original page to another page?
I am using ionic 4
<ion-item>
<ion-input #user2 type="tel" maxlength="14" minlength="4" [(ngModel)]="numpad"
name="userCount" (keypress)="numberOnlyValidation($event)"></ion-input>
</ion-item>
<ion-item (click)="openSelect()">
<ion-input [(ngModel)]="selectedCode"></ion-input>
</ion-item>
<ion-item style="display: none">
<ion-select #select1 [(ngModel)]="selectedCode">
</ion-select>
</ion-item>
Here's one solution. Assume the input is in home.page and the values will be routed to page2.page.
Update app-routing.module.ts and add a new route
{
path: 'page2/:code/:numpad',
loadChildren: () => import('./page2/page2.module').then( m => m.Page2PageModule)
},
Then you will want to take the values from home.page and navigate to page 2. There are a few different way to do this. In the example below I'm just using ionChange to call a function to route to page2.
home.page.ts
<ion-item>
<ion-input #user2 type="tel" maxlength="14" minlength="4" [(ngModel)]="numpad" name="userCount"></ion-input>
</ion-item>
<ion-item>
<ion-select [(ngModel)]="selectedCode" (ionChange)="valueChangedSoRouteToPage2()">
<ion-select-option *ngFor="let user of users" [value]="user.id">{{user.first + ' ' + user.last}}</ion-select-option>
</ion-select>
</ion-item>
Then in home.page.ts you can do something like this
valueChangedSoRouteToPage2() {
console.log('changed');
console.log(this.selectedCode);
console.log(this.numpad);
this.router.navigateByUrl('/page2/' + this.selectedCode + '/' + this.numpad);
}
Last step - update page2.page.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-page2',
templateUrl: './page2.page.html',
styleUrls: ['./page2.page.scss'],
})
export class Page2Page implements OnInit {
page2Code;
page2Numpad;
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit() {
this.page2Code = this.activatedRoute.snapshot.paramMap.get("code");
this.page2Numpad = this.activatedRoute.snapshot.paramMap.get("numpad");
console.log('code: ' + this.page2Code);
console.log('numpad: ' + this.page2Numpad);
}
}
Hope this helps.

Ionic 4: How to pre select values in an ion-select component

I am developing an Ionic 4 app.
I need to pass data from a list of users to a form in order to modify some attributes of this particular user.
I passed the data from the list (the user) to an other page containing the form. I saved this data in local variables in the .ts of the form.
Now, I have some trouble to make an ion-select component pre-select this data. I have no troubles for an ion-input though.
I tried to do so with a double data binding with [(NgModel)] and a value attribute but it didn't work.
Any help here will be appreciated.
Edit: Here is my code.
The .ts file:
serviceList: Service[];
isModifying = false;
username: string;
password: string;
firstName: string;
lastName: string;
service: number;
codivRH: any;
profil: string;
constructor(private sqlP: SqlProvider, private route: ActivatedRoute, private router: Router) {
this.route.queryParams.subscribe(params => {
if (this.router.getCurrentNavigation().extras.state) {
this.firstName = this.router.getCurrentNavigation().extras.state.userFirstname;
this.lastName = this.router.getCurrentNavigation().extras.state.userLastname;
this.service = this.router.getCurrentNavigation().extras.state.userService;
this.codivRH = this.router.getCurrentNavigation().extras.state.userCodiv;
this.profil = this.router.getCurrentNavigation().extras.state.userProfil;
this.isModifying = true;
}
});
}
Here is the .html file:
<ion-item>
<ion-label> Service </ion-label>
<ion-select [(ngModel)]="service" name="service">
<ion-select-option *ngFor="let mservice of serviceList" value="mservice.Id" ngDefaultControl> {{ mservice.Nom }} </ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label> CodivRH </ion-label>
<ion-select [(ngModel)]="codivRH" name="codiv">
<ion-select-option value="1"> Oui </ion-select-option>
<ion-select-option value="0"> Non </ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label> Profil </ion-label>
<ion-select [(ngModel)]="profil" name="profil">
<ion-select-option value="user"> Utilisateur</ion-select-option>
<ion-select-option value="admin"> Admin </ion-select-option>
<ion-select-option value="Superadmin"> SuperAdmin </ion-select-option>
</ion-select>
</ion-item>
Here is working example
in your ts
selected;
defaultList = [
{
id: 0,
key: "BILLPAYMENT",
value: "Wallet_1002"
},
{
id: 1,
key: "REQUESTMONEY",
value: "Wallet_1002"
},
{
id: 2,
key: "SENDMONEY",
value: "Wallet_1002"
},
{
id: 3,
key: "QUICKPAYMENT",
value: "Wallet_1002"
}
];
constructor() {
this.selected={
id: 0,
key: "BILLPAYMENT",
value: "Wallet_1002"
};
}
.html
<ion-item>
<ion-select [(ngModel)]="selected" [compareWith]="compareFn">
<ion-option *ngFor="let default of defaultList" [value]="default">{{default.key}}</ion-option>
</ion-select>
</ion-item>
I have the same problem using ReactiveForms. Here my form: update.html
<form *ngIf="datosBasicosForm" name="datosBasicosForm" [formGroup]="datosBasicosForm">
<ion-list>
<ion-item>
<ion-label position="floating">Tipo de Actividad </ion-label>
<ion-select id="field_tipoDeActividad" placeholder="Seleccionar" formControlName="tipoDeActividad"
[compareWith]="compareTipoDeActividad" >
<ion-select-option [value]="tipoDeActividadOption"
*ngFor="let tipoDeActividadOption of tipoDeActividads; trackBy: trackTipoDeActividadById">
{{tipoDeActividadOption.nombre}}</ion-select-option>
</ion-select>
</ion-item></ion-list></form>
Then in the update.ts I load some data to fill de tipoDeActividads array of TipoDeActividad and the variable actividad of Actividad from the DB with id passed as a parameter:
export class ActividadUpdatePage implements OnInit {
datosBasicosForm = this.formBuilder.group({
id: [],
tipoDeActividad: [null, [Validators.required]],
});
async ngOnInit() {
this.tipoDeActividadService.query()
.subscribe(data => { this.tipoDeActividads = data.body; }, (error) =>
this.onError(error));
this.activatedRoute.data.subscribe((response) => {
this.updateForm(response.data);
});
}
updateForm(actividad: Actividad) {
this.datosBasicosForm.patchValue({
id: actividad.id,
tipoDeActividad: actividad.tipoDeActividad,
});
}
As you can see I load everything in the ngOnInit and do a patch of the values received in the form.
But even when I click the ion-select and the option is selected, the problem is that it doesn't show the preselected value when the form load...
the compareWith function is as follows:
compareTipoDeActividad(first: TipoDeActividad, second: TipoDeActividad): boolean {
return first && second ? first.id === second.id : first === second;
}
So I'm thinking it may be something related to the type of object I'm dealing with? or with the asynchronous load calls that are not ready when the form is rendered?
Any help will be much appreciated, thanks.

How to get modal data on modal dismiss in Ionic 3?

I have a Page with a List. From that page I open a MODAL.
That modal contains a Text box and a Add Item Button.
When I enter an Item in the Box and Hit Add Item, I need to
1) Dismiss the Modal
2) Add the entered Item in the List in the Previous List
I need to do this via On Dismiss().
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: String;
constructor(public navCtrl: NavController, public modalCtrl: ModalController, public navParams: NavParams) {
}
ionViewDidLoad() {
this.newItem = this.navParams.get('data');
this.itemsArray = [
'Bread',
'Milk',
'Cheese',
'Snacks',
'Apples',
'Bananas',
'Peanut Butter',
'Chocolate',
'Avocada',
'Vegemite',
'Muffins',
'Paper towels'
];
this.itemsArray.push(this.newItem)
}
public addItem() {
let modalPage = this.modalCtrl.create(ModalPage);
modalPage.onDidDismiss(data => {
this.newItem = data;
});
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;
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.name};
this.viewCtrl.dismiss(data)
}
}
Your code seems to be fine overall.
Change this part.
public addItem() {
let modalPage = this.modalCtrl.create(ModalPage);
modalPage.onDidDismiss(data => {
this.itemsArray.push(data);
});
modalPage.present();
}
Change the name of your variable on the html or the TS file.
name to newItem or vice-versa
You are using [(ngModel)]="newItem" but in your TS file your using this.name
You're adding the item on ionViewDidLoad() but the new item arrives at modalPage.onDidDismiss()
Give it a try. I'll help you further if it still does not work.
First you need to pass object/string of item/data from you mode while you are closing the same
this.viewCtrl.dismiss(data);
And you have to subscribe model closing event at the page from where you have opened it for ex.
let modal = this.modalCtrl.create(ModelPage);
modal.onDidDismiss(data => {
this.badge = data;
});
modal.present();
After you can simply push you new item in to items array :)

How to write data into csv file from ionic form?

I am newbie to Ionic.
I have two fields in the form
<ion-item>
<ion-label floating>Name</ion-label>
<ion-input #name type="text"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>school</ion-label>
<ion-input #school type="text"></ion-input>
</ion-item>
<div padding>
<button block ion-button (click)="SaveForm()">Save data</button>
</div>
After user clicking on the save button, I want to save the data in csv format in local file system.
I tried
SaveForm()
{
var finalCSV = this.name.value+','+this.school.value;
alert('finalCSV');
$cordovaFile.writeFile(cordova.file.externalRootDirectory, 'data.csv', finalCSV, true).then(function(result){
alert('Success! Export created!');
}, function(err) {
console.log("ERROR");
})
}
In the same ts file I have added
import {File} from 'ionic-native';
declare var cordova:any;
const fs:string = cordova.file.dataDirectory;
File.checkDir(this.fs, 'mydir')
.then(_ => console.log('yay'))
.catch(err => console.log('boooh'));
I am getting following Error
Typescript Error Cannot find name '$cordovaFile'.
How to resolve this Error?
Is there any better approach to implement this?
import {Page, Platform} from 'ionic/ionic';
constructor(platform: Platform) {
this.platform = platform;
}
this.platform.ready().then(() => {
cordovaFile.writeFile(cordova.file.externalRootDirectory, 'data.csv', finalCSV, true).then(function(result){
alert('Success! Export created!');
}, function(err) {
console.log("ERROR");
})
}

How do I in ionic 2 pass data from a modal with a form on, to the home page?

Hi there can anyone help out. I am new to Ionic and Angular. I am trying to create a weather app in Ionic 2.
I have created a Home page with a Click event calling an AddWeather() function.
The function opens up a modal with a form attached. I am trying to pass data from the form on the modal back to the home page an output on the screen. I have tried ngModel but can't seem to get it working correctly.
Here is my Code: (home.ts)
import { Component } from '#angular/core';
import { NavController, ModalController, NavParams } from 'ionic-angular';
import { AddPage } from '../add/add';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public weatherList = [];
constructor(public navCtrl: NavController, public modalCtrl: ModalController) {
}
addWeather() {
let addWeatherModal = this.modalCtrl.create(AddPage);
addWeatherModal.present();
}
}
(add.html)
<ion-header>
<ion-navbar color="weatherbru">
<ion-title>Modal</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="CloseModal()"><ion-icon name="close"></ion-icon></button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content padding>
<form>
<ion-item>
<ion-label stacked>City</ion-label>
<ion-input type="text" ></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Country</ion-label>
<ion-select >
<ion-option value="us">United States</ion-option>
<ion-option value="uk">United Kingdom</ion-option>
</ion-select>
</ion-item>
<button ion-button block (click)="CloseModal()">Add Weather</button>
</form>
<div padding>
</div>
</ion-content>
(add.ts)
import { Component } from '#angular/core';
import { ModalController } from 'ionic-angular';
import { NavController, NavParams, ViewController } from 'ionic-angular';
#Component({
selector: 'page-add',
templateUrl: 'add.html'
})
export class AddPage {
constructor(public viewCtrl: ViewController, public navCtrl: NavController, public navParams: NavParams) {}
CloseModal() {
this.viewCtrl.dismiss();
}
}
In your html :
<form>
<ion-item>
<ion-label stacked>City</ion-label>
<ion-input [(ngModel)]="form.city" type="text" ></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Country</ion-label>
<ion-select [(ngModel)]="form.country">
<ion-option value="us">United States</ion-option>
<ion-option value="uk">United Kingdom</ion-option>
</ion-select>
</ion-item>
<button ion-button block (click)="CloseModal()">Add Weather</button>
</form>
In your add.ts file :
export class AddPage {
form : any; //Declare the form object to be bound to your html
constructor(public viewCtrl: ViewController, public navCtrl: NavController, public navParams: NavParams) {}
CloseModal() {
this.viewCtrl.dismiss(this.form); //Send back the form object when closeModal is called
}
}
In your home.ts :
addWeather() {
let addWeatherModal = this.modalCtrl.create(AddPage);
addWeatherModal.present();
addWeatherModal.onDidDismiss(data=>{ //This is a listener which wil get the data passed from modal when the modal's view controller is dismissed
console.log("Data =>", data) //This will log the form entered by user in add modal.
})
}