This maybe very simple and I have researched on here and elsewhere but I cannot seem to find a good answer to my query.
I am using Angular and have created a mat-menu-item with checkbox and name.
<section *ngFor="let group of groups;">
<div *ngIf="group?.length > 0">
<mat-menu-item (click)="$event.stopPropagation()">
<mat-checkbox checked = true
(click)="myMethod(group, **<aria-checked value>**)">
<p>{{group.name}}</p>
</mat-checkbox>
</mat-menu-item>
</div>
</section>
While I have tried using $event.checked to get the value of the mat-checkbox, it returns the same value for all the boxes. I found aria-checked is different for each section created and I would like to be able to use this value to pass it to myMethod.
Is this possible? If not, is there a way to show individual values on the created checkboxes in the ngFor?
Related
I would remove the blank first option from a select ng-model and put instead the first value of an array.
Here is my code:
<div class="col-9">
<select ng-model="chooseOrg"
formControlName="orgTypeId"
class="editmodal-object">
<option [ngValue]="orgType.id" *ngFor="let orgType of allOrgType" style="text-transform:uppercase;">{{orgType.description}}</option>
</select>
</div>
My array has no blank value inside, but it's composed of 5 object. I just want the first one always the default value of my select.
Since you are using ngmodel you should have it changed when you change the formControlName. I think having both makes it not working properly. So remove ngmodel and rely on formControlName and check for changes and set chooseOrg that way.
Another good thing to know is that you can set the default value for new FormControl() by having the default value 1 for example in the method like this:
new FormControl(1)
I made a stackblitz for you to show you what I mean. https://stackblitz.com/edit/angular-ivy-klwglz?file=src/app/app.component.html
I am trying to organize a drop down list that will display a single value to the user but will also pass back an array object upon changing the selection.
Currently I have an array called classificationresult that has 3 elements CLASSIFICATION_NAME, GROUP_ID, GROUP_NAME.
When a user selects a particular CLASSIFICATION_NAME I want to pass back the entire array result containing all 3 elements listed above.
Currently the code below works for everything EXCEPT showing the CLASSIFICATION_NAME in the drop-down box upon loading. It shows the list once you click, but it starts with a blank until it is clicked. Any way to fix this? I believe the display element is tied to [ngValue] but that is also what I am using to pass back the entire array versus just the one.
Any help would be greatly appreciated.
<p>Select Classification*</p>
<select [(ngModel)]="selectedClassification (ngModelChange)="changedClassification($event)">
<option *ngFor="let classificationresult of classificationresults" [ngValue]="classificationresult" >{{ classificationresult.CLASSIFICATION_NAME }}</option>
</select>
Summary -- I want my drop down list to always have a value shown to the user (value being the Classification Name) but when one is selected I want the entire array to pass to the changedClassification function. Also sometimes after a user selects from other drops down on this page they will also go blank, but if they are selected a second time they will populate.
If everything is working as you are expecting except the initial value being displayed, I wonder if you need a [compareWith] function. I don't know what your classificationresult model looks like, but if I had to take a guess, putting a [compareWith] function on your <select> element would fix the issue.
Here is an article explaining it a little more.
I made this Stackblitz as an example with using the [compareWith] function. In my demo I am using ReactiveForms, but the compareWith should still be the same.
For your code, it may look something like:
<p>Select Classification*</p>
<!-- add this [compareWith] -->
<select [compareWith]="myCompareFunc" [(ngModel)]="selectedClassification" (ngModelChange)="changedClassification($event)">
<option *ngFor="let classificationresult of classificationresults" [ngValue]="classificationresult" >{{ classificationresult.CLASSIFICATION_NAME }}</option>
</select>
In your .ts file:
export class YourComponent {
// all your component code..
/* compare function, change the logic to fit your needs */
myCompareFunc (classificationRes1: any, classificationRes2: any): boolean {
return classificationRes1 && classificationRes2
? classificationRes1.CLASSIFICATION_NAME === classificationRes2.CLASSIFICATION_NAME
: classificationRes1 === classificationRes2
}
}
If that doesn't fix your issue, you may need to post more of your .ts code and data models.
I want to display some data from a json but i can't simply add an offset to the index and show all te data from a certain offset but get
ERROR TypeError: Cannot read property 'id' of undefinedand the text in the div doesn't appear.
I have already tried to directly add a fixed number in the html file and it works (see the code below). But when it comes to use a variable "offset" (type:number) from typescript that is supposed to be updated with an input, the return type becomes undifined and the error appears. I also tried to use a method in my typescript file instead of doing the addition in the html file, and return the new index but it doesn't work and show the error. I also tried to call the method using {{addition(i,offset)}} and put the result in a variable that I use as an index but it still showing the error.
For exemple, this html file is working fine :
<ng-container *ngFor="let article of data; let i = index">
<ng-container *ngIf="i<(nbElements)">
<div (click)="checkArticle(data[(i+3)].id)">
<p class="text-center"> {{data[(i+3)][dataKey]}}</p>
</div>
</ng-container>
</ng-container>
The div reacts to my click and the text appears.
However, this html file is not working, even if the offset is set as 3 (as the html above) using an input in the parent component :
<ng-container *ngFor="let article of data; let i = index">
<ng-container *ngIf="i<(nbElements)">
<div (click)="checkArticle(data[(i+offset)].id)">
<p class="text-center"> {{data[(i+offset)][dataKey]}}</p>
</div>
</ng-container>
</ng-container>
The error appears.
The offset (type:number) is defined in my typescript file this way, and is changed by the parent component and can easily be displayed by the child component using console.log(offset):
export class AppColumnComponent implements OnInit {
#Input() offset : number ;
I expect the output to be texts showing the articles of my data json, but as I change the offset using an input like that data[(i+offset)] the result is an error, maybe it's impossible to use an other index using an other variable that a fixed number ?
Thank you for your support, it's my first post on stackoverflow i hope i did it well ! :)
If you want to make a pagination component, you should not rely solely on your HTML and some bindings.
Your component should have an "advanced" logic, in the sense that it should be able to know when it reaches the end/start of the collection (among other things).
Basically, this goes as follow :
Get the full collection (let's say 100 items)
Splice it to your item per page number (let's say 10, so results range is 0-10)
Test if items exist before the range
Test if items exist after the range
Allow/block page changing based on those variables.
This leaves you with
1 variable for the collection
1 variable (or 1 pipe) for the subset of the collection
1 variable for the items per page number
1 variable for the offset
2 booleans to disable pagination buttons.
Try working with this, and if you still have issues, then please provide a stackblitz with what you have tried !
You are accessing an index out of bounds.
data[(i+offset)] will be undefined for the last offset amount of elements in your data array so you are basically trying to do undefined.id which leads to your error.
You should change your method signature to only recieve the index as parameter and handle that case in your component.ts file
This question already has an answer here:
Where does Angular define "as local-var" behavior for *ngIf?
(1 answer)
Closed 4 years ago.
I have a question about declaring temporary variables in Angular template to use it for multiple element (childs) like: (Idea / Expected)
<ng-container *ngVar="let theValue = item.getValue()">
<div>{{ theValue }}</div>
<div [class.foo]="theValue == 42">foo</div>
</ng-container>
I already have a workaround for this. Just wrap the value in a array and use ngFor like: (Workaround)
<ng-container *ngFor="let theValue of [item.getValue()]">
<div>{{ theValue }}</div>
<div [class.foo]="theValue == 42">foo</div>
</ng-container>
But this is a bit dirty. - Is there an official solution?
My idea is to reduce the computing of the value over and over again for the same value. I just want to reuse the computed value for multiple childs and / or attributes.
I do not want to compute getValue() every time. Because I get the same value anyway. To hold the value temporary in a group element it can improve the performance and readability.
It should be possible without a custom directive.
I mean to have seen something like this before.
One possible solution is to 'cache' the return value of getValue(). This technique is called memoization. It works only on pure functions, meaning that for the same inputs, the output is always the same, and when function has no side effect.
You can use a decorator to achieve this in a straightforward manner, here is a project that might be useful to you: https://github.com/darrylhodgins/typescript-memoize.
Im using Angular material's for multipe choice purpose like mentioned in their site https://material.angular.io/components/select/overview (8th example).
I also have an array of items (key and value) which are a part of the choices([key:1 value:extra cheese, key:2 value:onion])... I want them to be automatically selected (probably using formController) ... how can I do this?
plus, after the user selected/ unselectedsome options how do i get a new array back ?
thank you in advance!
you need to use ngModel
<mat-select placeholder="Toppings" [formControl]="toppings"
multiple [(ngModel)]='defaultValue'>
and define this defulatValue in your component like this, or programaticly as you wish
defaultValue = [this.toppingList[1], this.toppingList[3]]
and you can get this variable when anything changes, it will contain your selected values. Took this example from material example, all works fine for me.