Like reaction in each element in ionic 3 - ionic-framework

I am using ionic 3, and looping ion-card with like using ngFor. I want to know how can I react with the user when user click the like/unlike button in each ion-card without reload the list.
<ion-card *ngFor="let u of users">
<p>{{u.name}}</p>
<button ion-button [hidden]="u.isliked=='1'" (click)="like(u.id)">like</button>
<button ion-button [hidden]="u.isliked!='1'" (click)="unlike(u.id)">unlike</button>
</ion-card>

You can make use of the *ngIf operator. This won't hide the element like the hidden property, but actually removes the element from the DOM.
(made u.isLiked into a boolean because I think it's cleaner that way, personal preference. Also changed (click) to (tap), see the answer on ionic2 tap vs click for more details.)
<ion-card *ngFor="let u of users">
<p>{{u.name}}</p>
<button ion-button *ngIf="u.isLiked" (tap)="like(u.id)">like</button>
<button ion-button *ngIf="!u.isliked" (tap)="unlike(u.id)">unlike</button>
</ion-card>
And in your ts:
like(userId) {
for(let user of this.users) {
if(user.id == userId) {
user.isLiked = true;
}
}
}
unlike(userId) {
for(let user of this.users) {
if(user.id == userId) {
user.isLiked = false;
}
}
}

Related

On hitting toggle button new page opens. How to avoid it?

I want to achieve below two functionalities :
toggle button ON/OFF. (Not want new details page to be open here)
clicking on CardView new details page should open.
On clicking cardView new details page opens, this working as expected.
but, currently on hitting toggle button new page opens. I need help to avoid it.
Html Code for cardview:
<ion-list *ngFor="let individual_room of data?.rooms">
<ion-list-header>
<ion-label>{{ individual_room.name}}</ion-label>
</ion-list-header>
<ion-grid>
<ion-row>
<ion-col *ngFor="let device of individual_room.devices">
<ion-card (click)="openDetailsWithState(device)">
<ion-col><img src="assets/icon/favicon.png" /></ion-col>
<ion-card-content>
<ion-card-title> {{ device.name }} <ion-badge item-end>{{ device.company }} </ion-badge> </ion-card-title>
<ion-toggle (ionChange)="deviceStatusChange(device)" [checked]="device.state =='ON'"></ion-toggle>
</ion-card-content>
</ion-card>
</ion-col>
</ion-row>
</ion-grid>
</ion-list>
home.page.ts :
deviceStatusChange(device: any) {
device.state = device.state === 'ON' ? 'OFF' : 'ON'
console.log('device toggle switch : ' + device.state)
}
openDetailsWithState(device: any) {
let navigationExtras: NavigationExtras = {
state: {
device: device,
},
}
this.router.navigate(['details'], navigationExtras)
}

Ionic 4 ion-select dynamically generated two dropdown based on first dropdown selection, How do I clear the second dropdown?

I have a form in my ionic project that has 2 dropdown menus of selection ion-select.
When the user selects an option in the first dropdown menu, it generates the options in the second dropdown list. This works well.
When I add new fields, I can reestablish the values of the first list displayed with [(ngModel)] = null in .ts, but I have not been able to reestablish those in the 2 drop-down list.
Image of error
,
image
This is the markup I have
<div formArrayName="sucursales" margin-bottom>
<!--generate new registration fields-->
<section [formGroupName]="i" *ngFor="let tech of form.controls.sucursales.controls; let i = index">
<ion-item>
<ion-icon name="list" item-start></ion-icon>
<ion-label>Departamento</ion-label>
<ion-select [(ngModel)]="locate" name="country" #country formControlName="country" (ionChange)="CountryChange($event)">
<ion-option *ngFor="let department of ubicacion; let i = index" value="{{department.departamento}}">{{department.departamento}}</ion-option>
</ion-select>
</ion-item>
<ion-item *ngFor="let x of selectedMunicipality">
<ion-icon name="list" item-start></ion-icon>
<ion-label>Municipio</ion-label>
<ion-select [(ngModel)]="locates" name="state" #state formControlName="state">
<ion-option *ngFor="let municipio of x.ciudades" value="{{municipio}}">{{municipio}}</ion-option>
</ion-select>
</ion-item>
And this id my code .ts:
this.http.get('http://localhost/ionic-php-mysql/colombia.json').map(res => res.json()).subscribe(
data => {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
this.ubicacion = data.colombia;
},
error => {
console.log("Oops!", error);
}
);
CountryChange(value: string) {
this.locate = null; //It works well
this.locates = null; //it does not work
this.selectedMunicipality = this.ubicacion.filter(item => item.departamento === value)
}
I want the second ion-select to select according to the first ion-select, and if I add new fields dynamically that the new values are independent.
I finally resolved.
buildGroup(): FormGroup {
return this.fb.group({
selectedSubcategory: [""],
});
CountryChange(value, index:number) {
this.productos.controls[index]selectedMunicipality = this.ubicacion.filter(item => item.departamento === value)
}
and in HTML
(ionChange)="CountryChange($event,i)"
<ion-item *ngFor="let x of tech.selectedMunicipality">

How do I abort an Ionic promise

I'm making a list of items and everytime that the user input some value it calls the listVendas function that searches immediately in the API, but this cause a bunch of requests, and some requests can finish before others, so my question is.
How can I abort a Promise so I can create a new one?
listVendas(event?: any) {
let codigovenda;
if (event) {
codigovenda = event.value;
}
if (typeof this.promise != 'undefined') {
// HOW DO I ABORT THE PREVIOUS PROMISE
}
this.promise = this.vendaProvider.getAll(codigovenda);
this.promise.then(data => {
this.vendas = data;
})
}
In Ionic you can use the rxjs switchMap operator and debounceTime operator to do this very easily.
example code
I've searched a lot, and you can't abort a promise, so my solution was to don't make the request everytime the user type something, instead of that I created a button to make the request
<form [formGroup]="searchForm" (ngSubmit)="listVendas()">
<ion-card class="search">
<ion-icon class="icon-search" name="search"></ion-icon>
<ion-input type="number" pattern="[0-9]*" value="" formControlName="codigovenda"></ion-input>
<ion-icon class="icon-camera" name="camera" (click)="scanBacode()"></ion-icon>
</ion-card>
<ion-row class="row-submit" justify-content-center>
<button ion-button full icon-start type="submit">
Buscar
</button>
</ion-row>
</form>

How do I update my page content?

I am trying to delete a card from my page, I want to remove it as soon as it is swiped and update the contents dynamically without using this code to refresh my entire page:
reloadPage() {
this.navCtrl.setRoot(this.navCtrl.getActive().component);
}
ion card:
<ion-card *ngFor="let e of tasks;let i = index" (swipe)="delete(i)">
<ion-card-header>
<ion-label>{{e.taskName}}</ion-label>
</ion-card-header>
<ion-card-content>
<p>{{e.task}}</p>
</ion-card-content>
</ion-card>
ts:
delete(i) {
this.tasks.splice(i, 1);
let newTask = JSON.stringify(this.tasks);
this.nativeStorage.setItem('tasks', newTask);
this.reloadPage();
}
Splicing the entry from your tasks array should suffice, no need to reload your page:
delete(i) {
this.tasks.splice(i, 1);
}
See this Stackblitz

Ionic 2 - ion-scroll fire event on scroll bottom

I have a page where I have a section which is scrollable. However I am not able to implement infinite scroll function inside the ion-scroll section. I know infinite-scroll applies on ion-content but how can I fire an event when the user scroll downs in an ion-scroll section.
<ion-content class="main-view">
<div class="overlay" tappable (click)="dismiss()">
</div>
<div (click)="CloseScreen()">
<ion-icon name="close" tappable class="close-modal"></ion-icon>
</div>
<div>
<div class="modal_content">
<ion-scroll scrollY="true" style="height:300px">
<ion-spinner class="loading-center" *ngIf="loadingCustomers"></ion-spinner>
<div class="customer-items">
<ion-item *ngFor="let customer of customersView.paginatedCustomers" tappable (click)="SelectCustomer(customer)">
<h6>
{{customer.BusinessName}}
</h6>
</ion-item>
</div>
<ion-infinite-scroll (ionInfinite)="LoadMoreCustomers($event)"> // NOT FIRING!
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-scroll>
....OTHER STUFF
</div>
</div>
</ion-content>
I will post this in case you or someone else is still looking for an answer.
Like you said ion-infinite-scroll would only applies to the ion-content even when placed inside an ion-scroll. So you could see it firing if you add some margin to your ion-scoll and try to scroll the page itself.
However, for your case, you may want to try something like this:
https://stackoverflow.com/a/42176764/4084776
If you want to check when you reach the bottom of the scroll you could add a dummy element and check if it is near the bottom of the scroll. See the example below.
...
#ViewChild(Scroll) ionScroll: Scroll;
#ViewChild("endOfScroll") endOfScroll: ElementRef;
updating: Boolean = false;
private threshold: number = 0.01; //1% This is similar to ion-infinite-scroll threshold
...
ionViewDidLoad() {
this.ionScroll.addScrollEventListener(this.scrollHandler.bind(this));
}
...
scrollHandler(evenman){
let endOfScroll = this.endOfScroll.nativeElement.getBoundingClientRect();
let ionScroll = this.ionScroll._scrollContent.nativeElement.getBoundingClientRect();
let clearance = 1 - ionScroll.bottom/endOfScroll.bottom;
if(clearance <= this.threshold){
this.updating = true;
// DO your work here
console.log(JSON.stringify({fen: endOfScroll.bottom, lis: ionScroll.bottom}));
this.updating = false;
}
}
...
...
<ion-scroll scrollY="true">
<ion-list>
<ion-item-sliding *ngFor="let machann of lisMachann.lisMachann let endeks = index" [class.active]="endeks == endeksKlik">
<ion-item (click)="ouveFenet(endeks)">
...
</ion-item>
<ion-item-options side="left">
...
</ion-item-options>
</ion-item-sliding>
<ion-item *ngIf="updating">
<ion-spinner class="loading-center"></ion-spinner>
</ion-item>
</ion-list>
<div #endOfScroll></div>
</ion-scroll>
...