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

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.

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.

Response with status: 0 for URL: null – getting this error when I run in simulator or web

I am developing a simple mobile maid android based app using Ionic framework and I am using laravel for my backend. I am getting ‘Response with status: 0 for URL: null’ this error when I run it in web or android simulator.
I could not be able to register a new user, when I used POSTMAN to check my restful API it works and I could be a able to register a new user. But when I run this app in simulator it keep on showing this ‘Response with status: 0 for URL: null’ error.
**auth-service.ts file**
import { Injectable } from '#angular/core';
import {Http, Headers} from '#angular/http'
import 'rxjs/add/operator/map';
let apiUrl = 'http://fypBackend.test/api/';
#Injectable({
providedIn: 'root'
})
export class AuthServiceService {
constructor(public http: Http) { }
register(data){
return new Promise((resolve, reject) => {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
this.http.post(apiUrl+'users', JSON.stringify(data), {headers: headers})
.subscribe(res => {
resolve(res.json());
}, (err) => {
console.log('Not Working')
reject(err);
});
});
}
}
**register.ts file**
import { Component} from '#angular/core';
import { NavController,LoadingController, ToastController } from '#ionic/angular';
import {AuthServiceService} from '../auth-service.service';
#Component({
selector: 'page-register',
templateUrl: './register.page.html',
styleUrls: ['./register.page.scss'],
})
export class RegisterPage{
loading: any;
regData = {name: '', icNumber: '', email: '',
password: '', phone: '', address: '',
cityState: '', houseType: '', category:''};
constructor(public navCtrl: NavController, public authService: AuthServiceService, public loadingCtr: LoadingController, private toastCtrl: ToastController) { }
doSignup(){
this.authService.register(this.regData).then((result)=>{
this.loading.dismiss();
this.navCtrl.pop();
}, (err) => {
this.presentToast(err);
});
}
async presentToast(msg){
const toast = await this.toastCtrl.create({
message: msg,
duration: 3000,
position: 'top',
color: 'dark',
});
toast.present();
}
}
**register.html file**
<ion-content padding>
<h2>Register Here</h2>
<form (submit) = "doSignup()">
<ion-item>
<ion-label stacked>Username</ion-label>
<ion-input [(ngModel)] = "regData.name" name = "name" type="text" placeholder = "Your Name"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>IC-Number</ion-label>
<ion-input [(ngModel)] = "regData.icNumber" name = "icNumber" type="number" placeholder = "Your IC-Number"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>E-mail</ion-label>
<ion-input [(ngModel)] = "regData.email" name = "email" type="email" placeholder = "Your E-Mail"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Password</ion-label>
<ion-input [(ngModel)] = "regData.password" name = "password" type="password" placeholder = "Your Password"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Handphone Number</ion-label>
<ion-input [(ngModel)] = "regData.phone" name = "phone" type="tel" placeholder = "Your Phone Number"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Address</ion-label>
<ion-input [(ngModel)] = "regData.address" name = "address" type="text" placeholder = "Your Address"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>City/State</ion-label>
<ion-input [(ngModel)] = "regData.cityState" name = "cityState" type="text" placeholder = "Your City/State"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>House Type</ion-label>
<ion-input [(ngModel)] = "regData.houseType" name = "houseType" type="text" placeholder = "Your House Type"></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Category</ion-label>
<ion-select [(ngModel)] = "regData.category" name = "category" type="text" placeholder = "Your Category">
<ion-select-option value="1" selected>Maid</ion-select-option>
<ion-select-option value="2" selected>Customer</ion-select-option>
</ion-select>
</ion-item>
<button ion-button block type = "submit">
SignUp
</button>
</form>
</ion-content>
This seems like a CORS issue, To avoid CORS problem you must use #ionic-native/HTTP plugin which is actually Advanced HTTP plugin for API calls.
Follow below steps to use this plugin
Step 1: Add Http native plugin
$ ionic cordova plugin add cordova-plugin-advanced-http
$ npm install --save #ionic-native/http
Installation Link : HTTP
Step 2: Import HTTP native plugin in your file where you wants to call API.
import { HTTP, HTTPResponse } from '#ionic-native/http';
Step 3: How to use this plugin for API call ?
constructor(public httpPlugin: HTTP) {
}
//Set header like this
this.httpPlugin.setHeader("content-type", "application/json");
//Call API
this.httpPlugin.get(this.url, {}, {}).then((response) => {
//Got your server response
}).catch(error => {
//Got error
});

Ionic 3 : How to make checkboxes behavior like radio-button

I have a list of checkboxes and I want to make them behave like radio button
How can I do this?
I tried using radio button but I am not getting the value of the user input so I dropped the idea of radio button and implement checkbox where i get the proper value & everything is perfect except the multiple checkbox selection I want to remove that
Here is my code:
selectOption(name, isChecked) {
if (isChecked === true) {
this.selectednames.push(name);
} else {
let index = this.removeCheckedFromName(name);
this.selectednames.splice(index, 1);
}
}
removeCheckedFromName(names: String) {
return this.selectednames.findIndex((ref) => {
return ref === names;
});
}
in my HTML
<ion-list>
<ion-list-header>
Choose Your Team
</ion-list-header>
<ion-item *ngFor="let names of name; let i = index">
<ion-label>{{name}}</ion-label>
<ion-checkbox item-left color="secondary" formControlName="name"
(ionChange)="selectOption(name, $event.checked)">
</ion-checkbox>
</ion-item>
</ion-list>
Any advices is highly appreciated
checkbox-stovr.page.html
<ion-header>
<ion-toolbar>
<ion-title>checkbox-stovr</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-list-header>
Choose Your Team
</ion-list-header>
<ion-item *ngFor="let name of names; let i = index">
<ion-label>{{ name['name'] }}</ion-label>
<ion-checkbox [(ngModel)]="name['isChecked']" (click)="toggle(name)">
</ion-checkbox>
</ion-item>
</ion-list>
</ion-content>
CheckboxStovrPage
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-checkbox-stovr',
templateUrl: './checkbox-stovr.page.html',
styleUrls: ['./checkbox-stovr.page.scss'],
})
export class CheckboxStovrPage implements OnInit {
names = [{ name: 'a' }, { name: 'b' }, { name: 'c' }, { name: 'd' },];
public selected: string;
constructor() { }
ngOnInit() {
}
public toggle(selected) {
for (let index = 0; index < this.names.length; index++) {
if (this.names['name'] != selected['name'])
this.names[index]['isChecked'] = null;
}
}
}
Do you want only one value selected at a time ??

Error: ExpressionChangedAfterItHasBeenCheckedError

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);
}

Dynamic dropdown not working properly in ionic 3

You can change here also ->https://stackblitz.com/edit/ionic-djze7u
home.html
<ion-content padding>
<ion-card>
<ion-card-content *ngFor="let item of users">
<ion-row>
<ion-label>{{item.name}}:</ion-label>
<ion-label>{{item.age}}</ion-label>
Here is the loop which I want to show value into dropdown according to item.term
<ion-select [(ngModel)]="check[item.age]">
<ion-option value="0" selected>0</ion-option>
<ion-option *ngFor="let v of caldrop(item.term)" value="{{v}}">
{{v}}
</ion-option>
</ion-select>
</ion-row>
</ion-card-content>
</ion-card>
</ion-content>
Home.ts
export class HomePage {
according to this term vale dropdown will show from 0 to this term value
users:any = [
{ name: 'Composite Factory', age: 1, term:2 },
{ name: 'Todd', age: 2, term:1 },
{ name: 'Lisa', age: 3, term:4 }
];
check:any = [];
constructor(public navCtrl: NavController) {
}
caldrop(myval:any){
console.log(myval)
let myarr:any = [];
for(let i=1;i<=myval;i++){
myarr.push(i);
}
return myarr;
}
}