How to set value of *ngFor dynamically in Angular2 - html

I want to set the value of '*ngFor' dynamically.
I have a div like : <div *ngFor="let section of anyArr; let i = index">
I want upper statement like this :
<div *ngFor="let section of {{anyArr}}; let i = index">`
I want 'dummyArr' as anyArr = myArr[0].Control[2] from .ts file.
Is this possible in Angular 2 ???

You could do this using getter in your component like this:
get anyArr() {
return myArr[0].Control[2];
}
Then in template use:
<div *ngFor="let section of anyArr; let i = index">`

Related

Angular does not update value to View when change in ngAfterViewInit

I have this in view
<span [ngStyle]="{width: optionActiveWindowSize}" class="option-active-window"></span>
<ng-container *ngFor="let op of options; let i = index">
<div [ngClass]="{active: i === activeIndex"}></div>
</ng-container>
Ts Code
ngAfterViewInit(): void {
const activeOption =
this.horizontalOptionRef.nativeElement.getElementsByClassName('active');
this.optionActiveWindowSize = activeOption[0].offsetWidth + 'px';
}
Value of optionActiveWindowSize does not change in the DOM after it was changed in afterViewInit.
Can you please tell me why and how to fix it?
There could be couple of problems.
Make sure, optionActiveWindowSize has a string value with px defined in the end like,
eg. optionActiveWindowSize = '20px'. Then,
[ngStyle]="{width: optionActiveWindowSize}"
should work.
I assume, optionActiveWindowSize has a numeric value like optionActiveWindowSize = 20, then you should change it as,
[ngStyle]="{ 'width.px': optionActiveWindowSize}"
OR
[style.width.px]="optionActiveWindowSize"
Hope, this will help !
NOTE: Forgot to mention as #M Fuat NUROGLU mentioned, span doesn't have width prop. So, you may want to change it to div.
You are binding styles after those styles are already rendered.
no event loop there to track it.
see detailed info from here : https://angular.io/api/core/AfterViewInit
If you want to imply those styles before your page is rendered.
use this :
const activeOption =
this.horizontalOptionRef.nativeElement.getElementsByClassName('active');
this.optionActiveWindowSize = activeOption[0].offsetWidth + 'px';
In your
ngOnInit()
method.
I found the reason. It's because changeDetection is ChangeDetectionStrategy.OnPush.
changeDetection: ChangeDetectionStrategy.OnPush

How to access a dynamically generated id of a HTML element with angular

<div *ngFor="let link of links; let i = index;">
<p>{{link.full}}</p>
<button [id]='i' (click)="copyToClipboard(copy) ">Copy</button>
</div>
How do I access the [id]="i" in my typescript file
Have a look at this demo:
[https://stackblitz.com/edit/angular-irxzeg?file=src%2Fapp%2Fapp.component.ts]
It includes suggestions from #Sam Herrmann
And with Renderer, to add Class
[https://stackblitz.com/edit/angular-mjvvp1?file=src%2Fapp%2Fapp.component.ts]
You don't need to add an id or to change 'manually' the label of button.
You can add a flag to know if link has been copied or not, inside your existing model.
For example:
export type Link = {
full: string,
copied: boolean
}
Then, inside your code you can set this flag to true:
copyToClipboard(link: Link) {
link.copied = true;
...
}
In template, just use this flag to adapt the label of button, and also to set a specific class on button (or elsewhere):
<div *ngFor="let link of links">
<p>{{link.full}}</p>
<button (click)="copyToClipboard(link)" [class.copied]="link.copied">
{{ link.copied ? 'Copied' : 'Copy' }}</button>
</div>
.copied {
background-color: green
}

How to Iterate JSON properties in TypeScript

My question is very simple, I have a following JSON Typescript Object and I like to Iterate trought the JSON properties
{"work_type":"Fabricación","work_type_resp":"Mesa","looking_for":"Relación Calidad/Precio","image":"https://s3-sa-east-1.amazonaws.com/online-quotation-images/153366018967.png","width":"22","high":"34","depth":"","modifications":"mod"}
The code used is the following angular TypeScript component:
export class DetailsOnlineQuoteModalComponent implements OnInit {
#Input() title;
#Input() values:string;
properties:JSON;
constructor(public activeModal: NgbActiveModal) { }
ngOnInit() {
this.properties=JSON.parse(this.values);
console.log(this.properties);
}
}
What I really need is to go through the key-value attributes of the JSON and show them in my HTML.
Many Thanks!
If you are using angular 6.1 use keyvalue pipe
<div *ngFor="let title of data | keyvalue">
{{title.key}}
</div>
For Angular 5
<div *ngFor="let key of dataKeys">
{{key}} ------------- {{data[key]}}
</div>
get dataKeys() { return Object.keys(this.data); }
Example:https://stackblitz.com/edit/keyvalue-pipe-qtaqnm
As per your comment, I'm assuming you want to do an ngFor on the HTML to display each one of the key-value pairs
<div *ngFor="let key of Object.keys(properties)">
{{properties[key]}} --> this is the value
</div>
You can get all the keys using Object.Keys and assign to a variable as follows,
this.properties=JSON.parse(this.values);
let response = Object.keys(this.propertie);
now you can use ngFor over it,
<div *ngFor="let key of response ">
{{properties[key]}}
</div>
component.ts
let obj = {"work_type":"Fabricación","work_type_resp":"Mesa","looking_for":"Relación Calidad/Precio","image":"https://s3-sa-east-1.amazonaws.com/online-quotation-images/153366018967.png","width":"22","high":"34","depth":"","modifications":"mod"}
this.keyOfObj = Object.keys(obj);
html
<div *ngFor="let key of keyOfObj ">
{{obj[key]}}
</div>
unfortunately seems to be NOT working (with keyvalue) with ANGULAR_9
see here for a comparison of full different way of doing: https://stackblitz.com/edit/angular9-iterate-on-object-attribute
otherwise the answer by defining a method to do the job is still working.

Angular: Send element from HTML

Is there a way to send through HTML the element as an attribute? For example:
In HTML:
<ul>
<li *ngFor="let item of items">
<my-component [ngClass]="{'whatever': checkElement(my-component)}">
</li>
</ul>
In ts file:
checkElement(el): boolean {
// dummy code
const size = el.getBoundingClientRect();
return size.bottom > 100;
}
I know there are several ways to get that element, but this will be used in a huge loop and I would like to prevent searching the element in the DOM (if possible).
Thanks!
You can you a template reference variable to refer to my-component like so:
<my-component [ngClass]="{'whatever': checkElement(myComponentVariableName)}" #myComponentVariableName>
and pass that as an argument to the method checkElement(). Note that here the type of myComponentVariableName will be HTMLInputElement.
Another way to access that from the .ts file would be to use #ViewChild() like so:
#ViewChild('myComponentVariableName') myComponentVariable: ElementRef;`.
Then you can use this.myComponentVariable anywhere inside the component.
If you are worried about having multiple my-components as it is inside an *ngFor, you can convert the #ViewChild statement to make it a list like so:
#ViewChildren(my-component) myComponentList: QueryList<my-component>;
Also, track the *ngFor by index, and send the index along with the template reference variable like so:
<li *ngFor="let item of items; let i=index;">
<my-component [ngClass]="{'whatever': checkElement(myComponentVariableName, i)}" #myComponentVariableName>
</li>
Inside the checkElement() method, access the particular my-component like myComponentList[i].
Sure, very easy :
export class ParentComponent {
this = this;
}
<my-element [parentElement]="this">
now in your second component
#Input('parentElement') parentElement: ParentComponent;

Switch / Toggle dynamically created components

I have two child component in parent component which dynamically created.
My goal is to switch/toggle between this components.
<div *ngFor="let device of devices; let i = index">
<app-standart-view [value]="device.value" (click)="SWICH TO DETAIL-VIEW"></app-standart-view>
<app-detail-view [value]="device.value" (click)="SWICH TO STD-VIEW"></app-detail-view>
</div>
Scenario:
When I click <app-standart-view> it hides itself and displays <app-detail-view>. But only for that clicked component index = i. The rest should don't change.
How can I do this?
Thank you
you can use *ngIf In ts file you will have to define a variable
hide:boolean =true
switchView(){
this.hide=!this.hide
}
and in html
<app-standart-view [value]="device.value" *ngIf= "hide" (click)="switchView()"></app-standart-view>
<app-detail-view [value]="device.value" *ngIf= "!hide" (click)="switchView()"></app-detail-view>
i'd use an *ngIf='device.toShow' directiv in your <app-detail-view>
And obviously setting the proper value of toShow in your methode that you use ater a click event on <app-standart-view>
<div *ngFor="let device of devices; let i = index">
<app-standart-view [value]="device.value" *ngIf="show" (click)="swichView(i)"></app-standart-view>
<app-detail-view [value]="device.value" *ngIf="!show" (click)="swichView(i)"></app-detail-view>
</div>
For specific index you need to pass index and check index
show:boolean = true;
swichView(index:number){
if(index === 1 ){
this.show = !this.show;
}
}