How to iterate through an array in an NgIf statement - Angular / Ionic - ngfor

<ion-card *ngFor="let house of (houses | async)">
<ion-list *ngIf="house.members[0] === currentUserId">
<ion-item button (click)="goToHouseDetailsPage(this.house)">
<ion-icon class="listIcon" item-left name="exit"></ion-icon>
{{ house.name }}
</ion-item>
</ion-list>
</ion-card>
This code is working and is displaying only the houses that the current user is a member of. I want to be able to iterate through this array, for when there are many members of one house.
Thanks

If you want to access the value of each item in house.members, then replace ngIf with ngFor like this:
<ion-card *ngFor="let house of (houses | async)">
<ion-list *ngFor="let member of house.members">
<ion-item button (click)="goToHouseDetailsPage(house)">
<ion-icon class="listIcon" item-left name="exit"></ion-icon>
{{ house.name }}
</ion-item>
</ion-list>
</ion-card>

Related

List is not displayed when using *ngSwitchCase

I want to bind 3 buttons to 3 different lists. I could use ion-segmentbut since I like the design over the segments I just do it with custom buttons. But now when I implement the *ngSwitchCase the lists are simply not displayed when I click on a button and I get this error Error: No value accessor for form control with unspecified name attribute
page.html
<ion-row [(ngModel)]="pre" [(ngModel)]="type" class="bg">
<ion-col col-4><ion-button value="own"</ion-button></ion-col>
<ion-col col-4><ion-button value="friends"</ion-button></ion-col>
<ion-col col-4><ion-button value="all" </ion-button></ion-col>
</ion-row>
<div [ngSwitch]="pre">
<ion-list *ngSwitchCase="'own'">
</ion-list>
<ion-list *ngSwitchCase="'friends'">
</ion-list>
<ion-list *ngSwitchCase="'all'">
</ion-list>
</div>
the issue here is that ion-row doesn't implement value accessor, which is required for using ngModel, you need to use an element that does implement value accessor.
for instance ion-segment
<ion-segment [(ngModel)]="type" [(ngModel)]="pre">
<ion-segment-button value="own">
Own
</ion-segment-button>
<ion-segment-button value="friends">
Friends
</ion-segment-button>
<ion-segment-button value="all">
All
</ion-segment-button>
</ion-segment>
it's weird to have two ngModels on one element, but you can if you'd like.

Show filled questionnaire

i'm creating a mobile app which allow the user to answer some question in a Questionnaire.
When the questionnaire is done, the user save it in LocalStorage.
When he go on the page, the user see all the previous answered questionnaire on buttons.
I would like to show the quesitonnaire previously filled but he can't change any answer.
How can I do that (disable any modifications)?
I'm using Ionic 3.
Here is a code sample of how i create a questionnaire.
<ion-item>
<ion-label>{{ 'PREVISIT_fever_or_infection' | translate }}</ion-label>
<ion-select [(ngModel)]="qObj.feverinfectionlastrelapse" interface="popover">
<ion-option value="yes">Yes</ion-option>
<ion-option value="no" checked>No</ion-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>{{ 'PREVISIT_overheated' | translate }}</ion-label>
<ion-select [(ngModel)]="qObj.overheatedlastrelapse" interface="popover">
<ion-option value="yes">Yes</ion-option>
<ion-option value="no" checked>No</ion-option>
</ion-select>
</ion-item>
<p>{{ 'PREVISIT_symptom_experienced' | translate }}<ion-icon name="add" class="more-icon"></ion-icon> {{ 'PREVISIT_symptom_experienced2' | translate }}</p>
<!-- Symptom list -->
<ion-item *ngFor="let symptom of symptoms">
{{symptom.label | translate}}
<ion-label>{{symptom.label | translate}} <ion-icon name="add" class="more-icon" [hidden]="!symptom.more"></ion-icon></ion-label>
<ion-checkbox [(ngModel)]="symptom.value"></ion-checkbox>
</ion-item>
<!-- more detailed questions list -->
<div *ngFor="let symptom of symptoms">
<h5 *ngIf="symptom.value&&symptom.more" class="more-detailed-questions-spacer">{{symptom.label | translate}}</h5>
<div *ngIf="symptom.value">
<ion-item *ngFor="let question of symptom.moreList">
<ion-label>{{question.name | translate}}</ion-label>
<ion-select [(ngModel)]="question.value" interface="popover">
<ion-option *ngFor="let condition of question.conditions" [value]="condition.value">{{condition.txt}}</ion-option>
</ion-select>
</ion-item>
Here is a screenshot of the questionnaire form.
You can use a Subject of variable type Boolean, and use the same variable to check if the user has loaded the details and disabled the form/elements using [disabled]="yourBoolean"
If you have single form you don't have to go for a Subject, you can just use a boolean variable
this.qObj = JSON.parse(localStorage.getItem('qObj'));
this.readOnly = true;
and
<ion-select [disabled] = "readOnly" [(ngModel)]="qObj.feverinfectionlastrelapse" interface="popover">
You could maintain a readonly state on your questionnaire component,
this.qObj = JSON.parse(localStorage.getItem('qObj'));
this.isReadOnly = typeof qObj !== 'undefined' && qObj !== null
And for your input controls you could assign this variable
<ion-item>
<ion-label>{{ 'PREVISIT_fever_or_infection' | translate }}</ion-label>
<ion-select [disabled] = "isReadOnly" [(ngModel)]="qObj.feverinfectionlastrelapse" interface="popover">
<ion-option value="yes">Yes</ion-option>
<ion-option value="no" checked>No</ion-option>
</ion-select>
</ion-item>
<ion-item *ngFor="let symptom of symptoms">
{{symptom.label | translate}}
<ion-label>{{symptom.label | translate}} <ion-icon name="add" class="more-icon" [hidden]="!symptom.more"></ion-icon></ion-label>
<ion-checkbox [disabled] = "isReadOnly" [(ngModel)]="symptom.value"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label color="primary">Inline Label</ion-label>
<ion-input [readonly]="isReadOnly" placeholder="Text Input"></ion-input>
</ion-item>

Name to large to display on ion-select option once you selected the value

I would like to display the large name on the area when I select an option from my select.
Actually, the name selected is : 'Speciall Academy Pizza' But on the screen is just displayed 'Special Academy...'.
On the next image you can see the problem:
And here the code from these selects:
<ion-item *ngIf="itemLevelSelected !== ''">
<ion-label>
level 1:
</ion-label>
<ion-select interface="popover" [(ngModel)]="categorySelected" (ngModelChange)="setCategorySelected(categorySelected)">
<ion-option *ngFor="let x of information">{{x.name}}</ion-option>
</ion-select>
</ion-item>
<ion-item *ngIf="categorySelected">
<ion-label>
level 2:
</ion-label>
<ion-select interface="popover" [(ngModel)]="subCategorySelected" (ngModelChange)="setSubCategorySelected(subCategorySelected)" >
<ion-option *ngFor="let x of subCategory" text-wrap>{{x.name}}</ion-option>
</ion-select>
</ion-item>
How could I display the full content of the large name?
Thanks.

How to get the values of ion-checkboxes in ionic?

I have 4 checkboxes. How do i get the values of those that are checked? What should i type in my typescript folder? I am trying to get the values so that i can save it into firebase. Here is my .html code.
<ion-content padding>
<ion-list>
<ion-item>
<ion-label>Bedrooms</ion-label>
<ion-checkbox [(ngModel)]="bedrooms" (ionChange)="updateBedrooms()"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Toilet</ion-label>
<ion-checkbox [(ngModel)]="toilets" (ionChange)="updateToilets()">
</ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Living Room</ion-label>
<ion-checkbox [(ngModel)]="livingroom" (ionChange)="updateLivingRoom()"></ion-checkbox>
</ion-item>
<ion-item>
<ion-label>Kitchen</ion-label>
<ion-checkbox [(ngModel)]="kitchen" (ionChange)="updateKitchen()">
</ion-checkbox>
</ion-item>
</ion-list>
<button (click)="onLoadTasks()" ion-button block>Choose Tasks<ion-
icon name="arrow-dropright"></ion-icon></button>
try this for the 4 ones
kitchen: boolean;
updateKitchen() {
console.log('new state:' + this.kitchen);
}

Ionic2,Angular2: [(ngModel)] for ion-checkbox or html checkbox?

What should the [(ngModel)] in the following case be,such that I can persist the state of the checkbox in the slide ? I need to slide from one slide to another upon selecting the checkboxes but when I click previous the state needs to be persisted.
Here is what I've for radio buttons. I just changed the radio buttons code into checkbox but it is not working.So I removed the [value] property and now if I select one checkbox, all of them are getting checked.
<ion-content padding>
<ion-slides>
<ion-slide *ngFor="let question of questions; let i = index">
<h1>{{ question.text }}</h1>
<span *ngIf="question.type=='singlecorrect'>
<ion-list radio-group [(ngModel)]="question.answer">
<ion-item no-lines no-padding *ngFor="let choice of question.choices">
<ion-label>{{ choice.choiceText }}</ion-label>
<ion-radio [value]="choice"></ion-radio>
</ion-item>
</ion-list>
</span>
<span *ngIf="question.type=='singlecorrect'>
<ion-list checkbox-group [(ngModel)]="question.answer">
<ion-item no-lines no-padding *ngFor="let choice of question.choices">
<ion-label>{{ choice.choiceText }}</ion-label>
<ion-checkbox></checkbox> // ERROR : no value accessor found.
</ion-item>
</ion-list>
</span>
<ion-row margin-top>
<ion-col>
<button (click)="showPrevious()" ion-button text-only [disabled]="i === 0" >Previous</button>
</ion-col>
<ion-col>
<button [disabled]="!question.answer" *ngIf="i < questions.length - 1" (click)="showNext()" ion-button text-only >Next</button>
<button [disabled]="!question.answer" *ngIf="i === questions.length - 1" (click)="showNext()" ion-button text-only >Submit</button>
</ion-col>
</ion-row>
</ion-slide>
</ion-slides>
</ion-content>
I'm storing the selected choices in an array called "answer".Refer this:Angular2,Typescript: How to put the radio button checked when in an array which displays one element per page?
Can someone help me? Thanks in advance.
I'm not sure if all questions should use checkboxes, or just some of them. I've modified the previous plunker to set some questions as a multiple choice question and left the rest as single choice questions. Please take a look at the new version of the plunker
This is the end result:
In the demo, now each question has the following properties:
{
text: 'Question 1',
multiple: false,
choices: [...],
answer: null
}
If the question allows multiple answers, then the answer property is initialized with an array, with one item per available choice of that question.
// Initialize the answers
this.questions.forEach(question => {
if(question.multiple) {
// Initialize an array with as many elements as the number of choices
question.answer = new Array(question.choices.length);
}
});
Then in the view we render radio items or checkbox items accordingly:
<ion-slides>
<ion-slide *ngFor="let question of questions; let i = index">
<h1>{{ question.text }}</h1>
<!-- Single choice: radio items -->
<div *ngIf="!question.multiple">
<ion-list radio-group [(ngModel)]="question.answer">
<ion-item no-lines no-padding *ngFor="let choice of question.choices">
<ion-label>{{ choice.choiceText }}</ion-label>
<ion-radio [value]="choice"></ion-radio>
</ion-item>
</ion-list>
</div>
<!-- Multiple choice: checkbox items -->
<div *ngIf="question.multiple">
<ion-item no-lines no-padding *ngFor="let choice of question.choices; let i = index">
<ion-label>{{ choice.choiceText }}</ion-label>
<ion-checkbox [(ngModel)]="question.answer[i]"></ion-checkbox>
</ion-item>
</div>
<span style="font-size: 1.2rem;">Selected answer: {{ question.answer | json }}</span>
<ion-row margin-top>
<ion-col>
<button (click)="showPrevious()" ion-button text-only [disabled]="i === 0" >Previous</button>
</ion-col>
<ion-col>
<button [disabled]="!question.answer" *ngIf="i < questions.length - 1" (click)="showNext()" ion-button text-only >Next</button>
<button [disabled]="!question.answer" *ngIf="i === questions.length - 1" (click)="showNext()" ion-button text-only >Submit</button>
</ion-col>
</ion-row>
</ion-slide>
</ion-slides>