I've try to use console.log to view the value, but noticeSet2[index] value is undefined. And when I print noticeSet, it will show all the data in the array. And I've try to print the index at console.log, and it show the index that match the array.
I try to create a sub menu in the sub menu of a main menu which is noticeSet and the main menu work just fine. I try the similar method and it doesn't work. all I need to solve now is to show the noticeSet2[index] value. Thanks
toggleItem(index, item) {
//this.noticeSet2[index].open = !this.noticeSet2[index].open;
console.log("here");
console.log(this.noticeSet2[0]);
console.log(this.noticeSet2[index]);
console.log(index);
let obj = {resident_id: this.resident_id,id: item.id}
this.authService.postData(obj, "getSubCategoryList").then((result) =>{
this.responseData = result;
if(this.responseData.feedData){
//this.noticeSet2[item.id] = this.responseData.feedData;
this.noticeSet3[this.noticeSet2[item.id]] = this.responseData.feedData;
this.isDataAvailable = true;
//console.log(this.noticeSet);
}
}, (err) => {
});
}
<ion-list *ngFor="let item of noticeSet; let i = index;" lines="none" class="accordion-list" detail="false"
no-padding >
<button ion-item tappble style="font-weight:bold;color:#424242;" (click)="getSubCategoryList(i,item)" [ngClass]="{'section-active':item.open,'section':!item.open}">
<ion-icon item-right slot="end" name="arrow-forward" *ngIf="!item.open"
style="font-size: 16px;font-weight: bold;"></ion-icon>
<ion-icon item-right slot="end" name="arrow-down" *ngIf="item.open"
style="font-size: 16px;font-weight: bold;color:rgb(74, 137, 220)"></ion-icon>
{{ item.title }}
</button>
<div *ngIf="noticeSet2[item.id] && item.open">
<ion-list *ngFor="let item of noticeSet2[item.id]; let j = index;" lines="none" class="child-list">
<button ion-item (click)="toggleItem(j,item)" *ngIf="item.title"
[ngClass]="{'child-active':item.open, 'child':!item.open}">
<ion-icon item-left slot="start" name="add" *ngIf="!item.open" style="font-size: 12px;font-weight: bold;">
</ion-icon>
<ion-icon item-left slot="start" name="close" *ngIf="item.open" style="font-size: 12px;font-weight: bold;">
</ion-icon>
<ion-label>
{{ item.title }}
</ion-label>
</button>
<div *ngIf="noticeSet3[this.noticeSet2[item.id]] && item.open">
<ion-list *ngFor="let item of noticeSet3[this.noticeSet2[item.id]]" class="child-list-list" lines="none">
<ion-item class="child-item" *ngIf="item.title">
<button ion-item >
{{item.title}}
</button>
</ion-item>
</ion-list>
</div>
</ion-list>
</div>
</ion-list>
This is because you use value inside the promise.
You have two ways to proceed:
First one is to use
.then( function() => { [...] }
instead of
.then((result) => { [...] }
it will works.
The Second one is to use special variable NOT inside your {}.
var that = this;
// ...
.then(function() { that.variable })
Hope this help.
Related
When ı run app and click notifications data appears in the template after a 10-15 seconds.
I checked the data with the console log when I was pulling datas, datas are coming normally(fast), the problem is that it shows late in HTML.
When I enter the notifications page : https://prnt.sc/11dtqkj
After waiting for 10-15 seconds :
https://prnt.sc/11dttn4
How can ı fix this problem ?
notifications.page.ts :
ionViewWillEnter(){
this.auth.currentUser.then(user=>{
this.userUid = user.uid
this.db.database.ref("/users/"+user.uid+"/notifications/").once("value",snap=>{this.notifications=[],snap.forEach(a=>{
this.db.database.ref("/users/"+a.child("who").val()+"/name").once("value",a2=>{let temp_a=a;
this.db.database.ref("/users/"+temp_a.child("who").val()+"/pp").once("value",a3=>{let temp_a2=temp_a; let a2_name = a2.val();
let type = temp_a2.child("type").val();
let not_key = temp_a2.key;
let name = a2_name;
let pp = a3.val();
let who = temp_a2.child("who").val();
let formId = temp_a2.child("formId").val();
let result = temp_a2.child("result").val();
if(type=="request"){
this.notifications.push({notKey:not_key,type:type,name: name,pp:pp,who:who,formId:formId});
}
else if(type=="response"){
this.notifications.push({type:type,name:name,pp:pp,who:who,result:result});
}
})
});
})
})
})
}
notifications.page.html
<ion-header>
<ion-toolbar color="primary">
<ion-buttons slot="start">
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title>Bildirimler</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list >
<div *ngFor="let item of notifications;let i index ">
<ion-item *ngIf="item.type=='request'">
<ion-avatar slot="start">
<img src={{item.pp}}>
</ion-avatar>
<ion-label style="white-space: pre-wrap;"><strong>{{item.name}}:</strong>adlı kullanıcı beraber kamp yapmak istiyor.</ion-label>
<ion-label><ion-button (click)="accept(item.who,item.formId,item.notKey,i)" style="width: 50%;" color="secondary"><ion-icon name="checkmark-outline"></ion-icon></ion-button>
<ion-button (click)="reject(item.who,item.notKey,item.formId,i)" color="light"><ion-icon name="close-outline"></ion-icon></ion-button></ion-label>
</ion-item>
<ion-item *ngIf="item.type=='response'">
<ion-avatar slot="start">
<img src={{item.pp}}>
</ion-avatar>
<ion-label style="white-space: pre-wrap;"><strong>{{item.name}}:</strong>adlı kullanıcı tarafından katılma isteğiniz {{item.result}}</ion-label>
</ion-item>
</div>
</ion-list>
</ion-content>
As per screenshot attachment, I would like all Ion Items sliding to open together when I trigger the Edit Button in a div,
Currently it only slides out the 1st delete ion items and the others remain unopened.
this is my code
HTML
<div class="editcontainer1" (click)="trigger()">Edit</div>
<ion-item-group *ngFor="let p of cart" #myItemsId >
<ion-item-sliding #slidingItem lines="none">
<div class="maincontainer">
<ion-item>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="danger"
(click)="removeCartItem(p)">
<div style="color: seashell;">Delete</div>
</ion-item-option>
</ion-item-options>
</div>
</ion-item-sliding>
</ion-item-group>
TS
trigger() {
this.itemSlidingList.open('end');
}
else {
this.itemSlidingList.close();
}
how do i modify to become opens all?
openAllSlides(item) {
let a = Array.prototype.slice.call(item.el.children)
a.map((val) => {
val.open();
})
}
thank you.
Screenshot
you can do something like:
<ion-list>
<ion-item-group #myItemsId> <!-- use ITEM id for group -->
<ion-item-sliding *ngFor="let item of items">
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option >Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-item-group>
</ion-list>
<ion-button (click)="openAllSlides(myItemsId)">open all slides</ion-button>
.ts
openAllSlides(item){
let a = Array.prototype.slice.call( item.el.children )
a.map((val)=>{
val.open();
})
}
I have set up several form that takes info for an upload logic: like one takes then picture, one the description, one other setting. Now I want that this is all stored in one single form, but while it still worked when using different form now I get this error:
ERROR TypeError: Cannot read property 'controls' of undefined
I have no idea why is that. I also cannot submit a new description which I want to make with <div (ngSubmit)="addTag()">
Here is my code:
html:
<form [formGroup]="categoryForm">
<ion-grid class="white">
<ion-row class="checkbox-tags rounded-checkbox-tags">
<ion-item mode="ios" lines="none" class="checkbox-tag rounded-tag">
<ion-icon name="images"></ion-icon>
<ion-checkbox formControlName="tag_1"></ion-checkbox>
</ion-item>
<ion-item mode="ios" lines="none" class="checkbox-tag rounded-tag">
<ion-icon name="camera"></ion-icon>
<ion-checkbox formControlName="tag_2"></ion-checkbox>
</ion-item>
</ion-row>
</ion-grid>
<ion-row class="range-item-row">
<ion-col size="12">
<div class="range-header">
<span class="range-value">{{ rangeForm.controls.dual.value.lower }}</span>
<span class="range-label">temperature</span>
<span class="range-value">{{ rangeForm.controls.dual.value.upper }}</span>
</div>
</ion-col>
<ion-col size="12">
<ion-range mode="md" class="range-control" formControlName="dual" color="danger" pin="true" dualKnobs="true" debounce="400"></ion-range>
</ion-col>
</ion-row>
<div (ngSubmit)="addTag()">
<ion-item>
<ion-input [disabled]="tagList?.length > 0" mode="md" formControlName="category" clearInput="true" placeholder="Tag" name="tagValue"></ion-input>
<ion-button [disabled]="!categoryForm.valid || tagList?.length > 0" type="submit" icon-only>
<ion-icon name="checkmark"></ion-icon>
</ion-button>
</ion-item>
</div>
</form>
<ion-chip class="chip" color="dark" *ngFor="let tag of tagList; let i = index">
<ion-icon name="pricetag"></ion-icon>
<ion-label class="set-label">{{ tag }}</ion-label>
<ion-icon name="close-circle" (click)="removeChip(i)"></ion-icon>
</ion-chip>
</ion-content>
<ion-footer>
<ion-button [disabled]="!tagList?.length > 0" (click)="confirm()" expand="block" type="submit">POST</ion-button>
</ion-footer>
typescript:
categoryForm: FormGroup;
...
addTag() { // properly access and reset reactive form values
const tagCtrl = this.categoryForm.get('category');
if (tagCtrl.value) {
this.tagList.push(tagCtrl.value);
this.tagInput = ''; // in order to have an empty input
}
}
ngOnInit() {
this.storage.get('image_data').then((imageFile) => {
this.imageForm.patchValue({
'image': this.storage.get('image_data')
});
});
this.categoryForm = new FormGroup({
'dual': new FormControl({lower: 100, upper: 150}),
'tag_1': new FormControl(true),
'tag_2': new FormControl(true),
'category' : new FormControl('', Validators.compose([
Validators.maxLength(25),
Validators.minLength(1),
Validators.required
])),
'image': new FormControl(null)
});
}
I have an ngFor which generates multiple ion-cards. Inside each card there's a button. The problem is that when I click on any of the buttons to change its text the text of other buttons also change. How can I prevent that?
<ion-card *ngFor="let item of unack, let i = index">
<ion-card-header>
<p [ngStyle]="{'color': buttonColor2}">{{status1}}</p>
</ion-card-header>
<ion-card-content>
<p align="center">Stores for order</p>
<img src="">
<div class="orderInfo">
<p>Delivery Time</p>
<p>{{item.delivery_from}} to {{item.delivery_to}}</p>
</div>
<div class="Custom">
<p>Customer</p>
<p>{{item.customer_name}} {{item.customer_surname}}</p>
</div>
</ion-card-content>
<ion-list>
<button class="Ack" *ngIf="HideACk" (click)="StartS(item)">
{{Acknowledge}}
</button>
You have to bind all attributes to object inside the unack array. example -> every object should have Acknowledge property.
<ion-content padding>
<ion-card *ngFor="let item of unack, let i = index">
<ion-card-header>
<p [ngStyle]="{'color': unack[i].buttonColor2}">{{unack[i].status1?unack[i].status1:""}}</p>
</ion-card-header>
<ion-card-content>
<p align="center">Stores for order</p>
<img src="">
<div class="orderInfo">
<p>Delivery Time</p>
<p>{{item.delivery_from}} to {{item.delivery_to}}</p>
</div>
<div class="Custom">
<p>Customer</p>
<p>{{item.customer_name}} {{item.customer_surname}}</p>
</div>
</ion-card-content>
<ion-list>
<button class="Ack" *ngIf="!unack[i]?.StartO" (click)="StartS($event, i)">
Acknowledge
</button>
<button class="Ack" *ngIf="unack[i]?.StartO" (click)="customer_pressed($event, i)">
Start Shopping
</button>
</ion-list>
</ion-card>
</ion-content>
this is your edited code Stackblits link
It should change in all because the interpolation that you are doing on Acknowledge variable is happening for all the cards. All cards are binding same Acknowledge variable, In your example, every button will consider same Acknowledge variable and value Acknowledged Order will be displayed. if you want you can create another property in item object, let say ack and assign some different text to it then render {{item.ack}}, check the following example
<ion-content padding>
<ion-card *ngFor = "let item of unack">
<button (click) = "StartS(item)" ion-button>
{{item.ack}}
</button></ion-card>
</ion-content>
Js file may look like :
export class HomePage {
public unack = [
{ name : 'apple', color : 'red', ack : 'Not acknowledged'},
{ name : 'orange', color : 'red', ack : 'Not acknowledged'},
{ name : 'penut', color : 'brown', ack : 'Not acknowledged'},
{ name : 'milk', color : 'white', ack : 'Not acknowledged'}
]
constructor(public navCtrl: NavController) {
}
StartS(item){
item.ack = item.ack == "Not acknowledge" ? "Acknowledged Order" : "Not acknowledge"
}
}
I'm trying to build a simple dynamic rate from 0 to 5 stars (and its middle values like x.5 [example 4.5] ) that receives a value from the javascript.
I looked for something with *ngFor but I'm not understanding how that works. Can someone explain / help me?
If it helps, for ionic, we have 3 type of stars available:
<ion-icon name="star"></ion-icon>
<ion-icon name="star-half"></ion-icon>
<ion-icon name="star-outline"></ion-icon>
For example if I receive from server a value rate = 3.5, it renders:
<ion-icon name="star"></ion-icon>
<ion-icon name="star"></ion-icon>
<ion-icon name="star"></ion-icon>
<ion-icon name="star-half"></ion-icon>
<ion-icon name="star-outline"></ion-icon>
I'm using javascript, no typescript.
Thank you so much :)
p.s. not sure if this title is the better, any suggestion is welcome :)
Here's one way to do it:
<ion-item>
<ion-icon *ngIf="myRating>=1" name="star"></ion-icon>
<ion-icon *ngIf="myRating>=2" name="star"></ion-icon>
<ion-icon *ngIf="myRating>=3" name="star"></ion-icon>
<ion-icon *ngIf="myRating>=4" name="star"></ion-icon>
<ion-icon *ngIf="myRating>=5" name="star"></ion-icon>
<ion-icon *ngIf="myRating%1!=0" name="star-half"></ion-icon>
<ion-icon *ngIf="myRating==0" name="star-outline"></ion-icon>
<ion-icon *ngIf="myRating<=1" name="star-outline"></ion-icon>
<ion-icon *ngIf="myRating<=2" name="star-outline"></ion-icon>
<ion-icon *ngIf="myRating<=3" name="star-outline"></ion-icon>
<ion-icon *ngIf="myRating<=4" name="star-outline"></ion-icon>
</ion-item>
It takes up more space in the HTML, but doesn't require any additional javascript. Here, myRating is the star value. I tested it for all 11 possible values.
If you have an array like
value = ['star', 'star', 'star', 'star-half', 'star-outline'];
you can use ngFor to render your HTML like
<ion-icon *ngFor="let icon of icons" [name]="icon"></ion-icon>
or depending on what name is (property or attribute)
<ion-icon *ngFor="let icon of icons" name="{{icon}}"></ion-icon>
An alternative would be to create a function with switch case or if to return the type of the icon, to clean code html.
html:
<Ion-item>
<Ion-icon [name]="validate(myRating)"> </ion-icon>
</Ion-item>
function:
Validate(e:string): string {
Let res;
if (e> 1){
res="star";
}
else {
res="star-outline";
}
Return result;
}
I've reached this solutions using the tips that you guys provided:
function printRating (rating) {
let max_rate = 5;
let rounded_rating = Math.round(rating);
let array_stars = new Array(max_rate);
array_stars.fill('star-outline');
for(let i=0; i < rounded_rating; i++) {
array_stars[i] = 'star';
if(i === rounded_rating - 1 && rating % 1 !== 0) {
array_stars[i] = 'star-half';
}
}
return array_stars;
}
In my component I've associated to a variable the result array
this.stars = this.printRating(this.seller.rating);
And finally in the view I printed based on the result array
<ion-icon *ngFor="let star of stars" name="{{star}}"></ion-icon>
Hope this helps someone!