Reference ngFor value in component - html

I have a nested ngFor statement. I need to retrieve the value of my first ngFor on button click.
I have tried the following:
use template reference variable
use attribute binding
use Input decorator
This is my code:
<mat-expansion-panel *ngFor="let item of Datasource;">
<mat-expansion-panel-header style="display:flex" class="mat-row">
{{item.Header}}
</mat-expansion-panel-header>
<mat-selection-list [(ngModel)]="selectedOptions">
<mat-list-option *ngFor="let line of item.match; let i= index;" [value]="line">
<div class="container-name">
<div class="col-6">{{i}} - {line.user.Name }} vs {{ line.user.Address }}</div>
</mat-list-option>
</mat-selection-list>
<div style="text-align:center; padding: 20px">
<button mat-raised-button color="primary" (click)="submit()" type="submit">Add</button>
</div>
</mat-expansion-panel>
Can this be achieved?

Well, you need to clone that object properties first. As that object is linked to the template, when you manipulate it, it is manipulated on template too. You can use var obj = Object.assign({}, actual obj) and then do the manipulation on obj instead of actual one. Then it will not get affected in template. Hope it helps.

Related

How can I convert input text on HTML to individual box-like structures each time user types a word separated by comma (see picture)

I would like to know how I can convert text data into individual boxes as shown in the picture each time user enters a word separated after a comma (I am currently creating this as an input field on Angular)
You can simply use a variable with ngModel and a *ngFor over this variable.split(',')
<input [(ngModel)]="name">
<ng-container *ngIf="name">
<div *ngFor="let item of name.split(',')">
{{item}}
</div>
</ng-container>
NOTE: You can use mat-chip-list in the way
<mat-chip-list *ngIf="name">
<mat-chip
*ngFor="let item of name.split(',');let i=index">
{{ item }}
<button matChipRemove>
<mat-icon (click)="remove(i)">cancel</mat-icon>
</button>
</mat-chip>
</mat-chip-list>
where
remove(index:number)
{
const list=this.name.split(",") //get the list
list.splice(index,1) //remove the element at position "index"
this.name=list.length?list.join(','):null //give value to name using join
}
stackblitz
NOTE: If you only need the "list" based in a variable just give value to the variable
Looks like you are looking for something like Angular Material Chips.
https://material.angular.io/components/chips/examples

Change dynamically style in Angular with ngfor array data

I want to set the width as dynamically with the data that i am gonna take from the array. But angular doesn't let me set it with usual way. How can i handle it ?
<div *ngFor="let item of products">
<div [style.width.px]="{{ item.size }}" class="Holiday"></div>
</div>
you do not need {{ }} when you're using [].
change [style.width.px]="{{ item.size }}" to [style.width.px]="item.size" and it should work.
Use ngStyle to apply dynamic styles.
<div *ngFor="let item of products">
<div [ngStyle]="{ 'width' : item.size+'px' }" class="Holiday"></div>
</div>
Demo : https://stackblitz.com/edit/angular-fel5sk

Problem with managing my *ngFor for array object

My object is:
{
"name": "OCA Netflix",
"workflowNames": [
"OCA-Netflix-Action",
"OCA-Netflix-Action-v2"
]
}
When I use ngFor in my html i use:
{{ usecase.workflowNames }} and I see elements separated by ",".
How can i insert in my code to see elements in a column?
EXAMPLE:
Not: OCA-Netflix-Action, OCA-Netflix-Action-v2
But:
OCA-Netflix-Action
OCA-Netflix Action-v2
You can use *ngFor directive with ng-container and add br tag to provide a new line.
<ng-container *ngFor="let v of usecase.workflowNames; let l = last;">
{{v}}<br *ngIf="!l"/>
</ng-container>
Use below code in html
<div *ngFor="let item of usecase.workflowNames;let i=index;">
<div>
{{item}}<br/>
</div>
</div>

Is there a way to use iteration inside an object in html in angular?

Here's how my html code is looking:
<div *ngFor="let historyArticle of historyArticles; let i=index">
<div [innerHTML]='historyArticle[i].fields.text | mdToHtml'></div>
</div>
I want to target the every object inside the historyArticle array. Writing {{i}} inside a div gives me the index number for each entry but I want to use that to target the correct text field in each entry
You don't need the i index at all in this case. historyArticle itself is the object you want:
<div *ngFor="let historyArticle of historyArticles">
<div [innerHTML]='historyArticle.fields.text | mdToHtml'></div>
</div>
Using *ngFor in Angular is basically looping through an array.
So doing :
for (let i = 0; i < this.historyArticles.length; i++) {
// do something e.g console.log(this.historyArticles[i].fields.text);
}
Is pretty much the same as :
<div *ngFor="let historyArticle of historyArticles">
<span>{{ historyArticle.fields.text }}</span>
</div>
Hope it helps you understand that in this case you don't need to use i = index
try this.
<div *ngFor="let historyArticle of historyArticles; let i=index">
<div>{{historyArticle[i].fields.text | mdToHtml}}</div>
</div>

Do different things in the same function depending on which html component called that function

I am making a basic toggle app in angular.I have two toggle buttons.I am displaying a message in toggle.I want to call the same function on toggle change but do different things depending on which button was toggled.Is it possible or do I have to use two different functions? Thanks in advance for the help.
Here is my template code:
<mat-card class="card" fxLayout="column" fxLayoutAlign="center center" >
<form class="example-form" [formGroup]="formGroup" (ngSubmit)="onFormSubmit()" ngNativeValidate>
<mat-action-list>
<mat-list-item > <mat-slide-toggle
(change)="onChange($event);displayMessage($event)" formControlName="Policy1" >
<span class="label">{{message}}</span></mat-slide-toggle></mat-list-item>
<mat-list-item > <mat-slide-toggle (change)="onChange($event)" formControlName="Policy2">Policy2</mat-slide-toggle></mat-list-item>
</mat-action-list>
<p>Form Group Status: {{ formGroup.status}}</p>
<button mat-raised-button [disabled]="disable" class="button" type="submit">Save Settings</button>
</form>
</mat-card>
The funtion that I'm calling from the toggle button:
displayMessage(e){
if(e.checked)
{
this.message = 'Toggled';
}
else
this.message = 'Slide';
}
The $event object from the (change) emitter has a srcElement that you can refer to when you want to find out which element caused the change.
If you want to retrieve the id of the element that called the function you do so with event.srcElement.id
You can pass more arguments to the handler:
<mat-slide-toggle *ngFor="let item of thingsToDo; let i = index"
(change)= "onToggle($event, item.id, i)">
onToggle = (event, id, indexInArray) => { //...