Is there a way to pass data from ionic select using IonChange event? - vuejs3

I have an ionic vue select which I am populating with an array and using a v-for to loop through the data. I want to pass the selected value when I open the select menu and click OK. Instead of that 5 being passed on I want to pass whatever value is selected in the v-for in this case whatever value is in drop[1] I want to pass that into my emitData function. Below is my code:
<template>
<ion-list>
<ion-item>
<ion-select #ionChange="emitData(5)" id="" placeholder="Select Topic">
<ion-select-option aria-checked="true" v-for="drop in dropData" v-bind:key="drop[1]" :value="drop[1]">{{ drop[0] }}</ion-select-option>
</ion-select>
</ion-item>
</ion-list>
Is there a way to achieve this?

Related

method gets called multiple times in angular material autocomplete

We have created a component using Angular material's autocomplete. To display the options, we are traversing through an array of 51 objects. I am applying a CSS class to the already selected option. The isAccountingTypeSelected method determines whether the option was selected or not.
The method gets called 51*28 = 1428 times. I don't seem to understand the reason? It should only be called 51 times, shouldn't it?
<mat-form-field class="full-width">
<input type="text" matInput #autoCompleteInput [formControl]="autocompleteForm" [matAutocomplete]="auto" placeholder="Choose Accounting Type" aria-label="Number">
<span matSuffix class="close-icon hover" *ngIf="autoCompleteInput.value" (click)="clearAll($event)"></span>
<span matSuffix class="arrow-drop-down-icon hover" (click)="openPanel()"></span>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="accountingTypeSelected($event)">
<mat-option *ngFor="let accountingType of filteredAccountingTypes | async" [value]="accountingType.code">
<span class="accounting-type-options" [class.selected]="isAccountingTypeSelected(accountingType.code)">
{{ accountingType.name + ' (' + accountingType.code + ')' }}
</span>
</mat-option>
</mat-autocomplete>
</mat-form-field>
isAccountingTypeSelected(code: string): boolean {
console.log('I was called');
if (this.selectedAccountingTypes.find((accountingType: AccountingType) => accountingType.code === code)) {
return true;
}
return false;
}
Angular uses changedetection lifecycle multiple times to check if the function has changed for [class.selected] or ngClass. If you use function, it will call multiple times. For this reason the use of function is not advised when you bind, instead you should calculate the values in your component.ts file and just bind the values to ngClass or [class].
Example: Stackblitz
N.B: We know when we change selected value it triggers a event change, we can calculate it and attach the calculation result to the [class.my-class] or ngClass.
Angular is gonna evaluate that expression every time it checks for changes, which in your case might be the css being added to your span elements.
Calling methods from the template in a for loop is not the best approach because they are called very often. You should instead store the result in a property and bind to this property instead.
It is a bind problem. Angular checks more times the result value. You can try with ChangeDetectionStrategy.CheckOnce
Your ngFor loop needs track a specific id so it won't re-render for nothing. Try this:
<mat-option *ngFor="let accountingType of filteredAccountingTypes | async; trackBy: trackByCode"[value]="accountingType.code">
</mat-option>
Then you add this function:
trackByCode(index: number, accountingType: yourType): string {
return accountingType.code;
}

How to display multiple selected values in ion select?

I am using developing an PWA with Ionic 4. while using ion-select for selecting multiple values like this.
<div class="form-group">
<ion-item>
<ion-icon slot="start" name="briefcase"></ion-icon>
<ion-label floating color="primary">Business Unit *</ion-label>
<ion-select multiple="true" placeholder="Select Business" (ionChange)="onBuSelectChange($event)"
formControlName="businessUnit" class="form-control"
[ngClass]="{'is-valid' : submitted && f.businessUnit.errors}">
<ion-select-option *ngFor="let unit of listBusinessUnit" [value]="unit.ID">
{{unit.BusinessUnitDesc}}
</ion-select-option>
</ion-select>
<h1 *ngIf="submitted && f.businessUnit.errors && f.businessUnit.errors.required" floating>*</h1>
</ion-item>
</div>
I am getting following output where user is only able to see text of first selected value of ion-options.
I tried overriding css with the following with no success.
.select-text {
-ms-flex: 1;
flex: 1;
min-width: 190px;
font-size: inherit;
text-overflow: ellipsis;
white-space: pre-line;
overflow: hidden;
}
This is late, but I was facing the same problem in my project, The selected options didn't fit inside select item.
The way I was able to solve it is creating an additional element just to show the results (I use popover interface for ion-select element). I know this is not quite a solution, but still it works and looks decent. Maybe someone else can suggest a better way, I would prefer cleaner solution, but for now this is the only way I could handle this.
This is my solution based on your example:
<div class="form-group">
<ion-item>
<ion-icon slot="start" name="briefcase"></ion-icon>
<ion-label floating color="primary">Business Unit *</ion-label>
// I render select hidden
<ion-select multiple="true" placeholder="Select Business" formControlName="businessUnit" interface="popover" #select>
<ion-select-option *ngFor="let unit of listBusinessUnit" [value]="unit.ID">
{{unit.BusinessUnitDesc}}
</ion-select-option>
</ion-select>
// And this is visualization part. I chose chips for values visualization as it looks nicer
<ion-item lines="none" (click)="select.open()"> // <- here I use open() function to trigger open command of select
<ion-icon slot="end" name="caret-down-outline" class="attributi__icon"></ion-icon>
<ion-label color="tertiary" class="attributi__label">Business units</ion-label>
</ion-item>
<ng-container *ngFor="let unit of listBusinessUnit">
// here I use formControlgetter to get the current value ofselect and show only the selected items
<ion-chip *ngIf="businessUnit.value.includes(unit.id)" color="dark" outline="true">{{unit.BusinessUnitDesc}}</ion-chip>
</ng-container>
</ion-item>
</div>
And this is the result, but on my project where I use it.
(I don't have enought reputation to post images so here are the links)
Here are the chips
And here is select popup
try this on your css, this work for me.
ion-select::part(text) {
white-space: normal !important;
word-wrap: break-word !important;
}
you can refer to this :
https://ionicframework.com/docs/api/select#styling-select-element

Passing Ionic checkbox values to Firebase

I got a problem while updating my Ionic checkbox values to Firebase.
Here is my HTML:
<ion-list>
<ion-item>
<ion-label>Problemfeld 1</ion-label>
<ion-checkbox checked="false" [(ngModel)]="problemfeld1" name="problemfeld1"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Problemfeld 2</ion-label>
<ion-checkbox checked="false" [(ngModel)]="problemfeld2" name="problemfeld2"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Problemfeld 3</ion-label>
<ion-checkbox checked="false" [(ngModel)]="problemfeld3" name="problemfeld3"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Problemfeld 4</ion-label>
<ion-checkbox checked="false" [(ngModel)]="problemfeld4" name="problemfeld4"></ion-checkbox>
</ion-item>
</ion-list>
<button ion-button (click)="updateProblemfeld()" [navPush]="problemdefinitionPage">Weiter</button>
This is the function in my Ionic Page:
updateProblemfeld(problemfeld1, problemfeld2,problemfeld3,problemfeld4) {
this.szenarioProvider.updateProblemfeld(problemfeld1, problemfeld2, problemfeld3, problemfeld4);
}
And this is how I pass it to Firebase:
updateProblemfeld(problemfeld1: boolean, problemfeld2: boolean, problemfeld3: boolean, problemfeld4: boolean): firebase.Promise<any> {
return firebase.database().ref('/szenarioData')
.child(firebase.auth().currentUser.uid)
.child('problemfeld').update({
problemfeld1: problemfeld1,
problemfeld2: problemfeld2,
problemfeld3: problemfeld3,
problemfeld4: problemfeld4,
});
}
And this is what the Error looks like:
Firebase.update failed: First argument contains undefined in property 'szenarioData.hR4feTPka8fuMDGK3YV0nFrDs1A3.problemfeld.problemfeld1'
Can you think of a solution for this?
Thanks in advance.
My god,
I looked for a solution for 2 days till I decided to ask this question.
And 30 minutes after asking I found it:
Button in the HTML document needs to be like this:
<button ion-button (click)="updateProblemfeld(problemfeld1, problemfeld2, problemfeld3, problemfeld4)" [navPush]="problemdefinitionPage">Weiter</button>
I simply forgot to pass the values...

Dynamically loading pages with parameters (Ionic 2 + Angular 2)

I am creating a recipe app, I have different categories that I want to dynamically load on click. To pull recipes I have a url (http get request) which I want to extend with a string depending on what category i click on. I understand that this can be done with parameters but I do not understand how this works as I am new to angular and Ionic.
The base url would be
http://api.yummly.com/v1/api/recipes?_app_id=/////&_app_key=/////
On the end I would want to add either one of these.
396^Dairy-Free
393^Gluten-Free
391^Nut-Free
393^Wheat-Free and so on. Could someone please give me an idea on how to implement this
My HTML currently is
<ion-item [navPush] = "listingPage" detail-push>
<img src="http://placehold.it/500x500">
<h1>Glueten Free</h1>
</ion-item>
<ion-item>
<img src="http://placehold.it/500x500">
<h1>Category 2</h1>
</ion-item>
<ion-item>
<img src="http://placehold.it/500x500">
<h1>Category 3</h1>
</ion-item>
<ion-item>
<img src="http://placehold.it/500x500">
<h1>Category 4</h1>
</ion-item>
and HTTP request is
this.http.get('http://api.yummly.com/v1/api/recipes?_app_id=////&_app_key=//////')
.map(res => res.json())
.subscribe(data => {
// we've got back the raw data, now generate the core schedule data
// and save the data for later reference
console.log(data);
this.listing = data.matches;
resolve(this.listing);
});
});
Currently I only have 1 url loading on a page, but I want this to change depending on what category selected. Many thanks
You have to pass the category id when the user will select the category and then call the function and pass the category id to that function. In that function, call the http method and you can use the category id in the URL.
<button click="getData(this.value)"></button>
In ts.file
getData(cat_id : any){
......
you can use cat_id here in URL and call http method
......
}

Ionic2. ion-option is not checked Visually

I have this ion-option inside a ion-list:
<ion-select [(ngModel)]="year">
<ion-option checked="true">
{{year}}
</ion-option>
<ion-option *ngFor="#year of years">
{{year}}
</ion-option>
</ion-select>
And inside the Page/Component I set:
this.year = '2016';
this.day = 30;
this.month = 'Jan';
Visually it's not checked, technically, it is.:
These are the options:
As it seems it must be a number not string...
How can I solve this?
I think what you are trying to accomplish is something like this:
<ion-select [(ngModel)]="yearModel">
<ion-option *ngFor="#year of years" value="{{year}}">
{{year}}
</ion-option>
</ion-select>
This will show the list of years in your years array, and will check the one you have in yearModel (I used a different variable name for clarity).
For example if you do this.yearModel="2016" in you page file, it will check the year 2016.

Resources