Lets say I have variable call myvariable and I want to update the value from 1# boolean to 2# object
export class controller extends component {
1# let myvariable = true;
2# click event would update this.myvariable = { dataNew = 20 }
3# dataView: myvariable ;
}
On 2# I want to update myvariable to an object with value dataNew = 20, will my component understand an update 3# dataView to new value on realtime?
Yes, it's doable although it's not recommended.
Assign myvariable to type any.
import { Component, VERSION } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular ' + VERSION.major;
myvariable: any = true;
update() {
this.myvariable = {dataNew: 20};
}
}
https://stackblitz.com/edit/angular-ivy-spsiuq
Related
I am trying to call a function everytime my ngFor is done loading data from my API.
but the callback is only triggering on first load of the ngFor.
how can I execute the callback everytime my ngFor is changed;
I used this answer: https://stackoverflow.com/a/38214091/6647448
here is what I have so far...
HTML
<button class="btn" (click)="changeDate()"></button>
<div *ngFor="item of items; let last = last">
<div>{{item}}{{last ? ngForAfterInit() : ''}}</div>
</div>
TS
this.ngForIsFinished = true;
ngForAfterInit() {
if (this.ngForIsFinished) {
this.ngForIsFinished = false;
}
}
changeDate() {
// this is where i trigger my ngFor to change its content
}
The person who answered said that you just need to set the ngForIsFinished back to true but I am having a hard time where to set it on my code.
Try to use ChangeDetectionStrategy.OnPush and last variable of ngFor. Because ChangeDetectionStrategy.Default always checks methods, so fooMethod(...) will be called multiple items:
<div *ngFor = "let title of iterated; let i=index; let last=last">
{{last ? fooMethod(last) : '' }}
</div>
yourComponent.ts:
import { Component, ChangeDetectionStrategy } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
name = 'Angular 4';
iteratedData = [
{"title":"test1","description":"foo","name":"name1"},
{"title":"test2","description":"foo","name":"name2"},
{"title":"test3","description":"foo","name":"name3"},
{"title":"test4","description":"foo","name":"name4"}
];
fooMethod(v) {
if (v)
console.log(`This is from the method ${v}`);
}
}
UPDATE:
After you've loaded data you should call slice method as Angular 2 change detection strategy doesn't check the contents of arrays or object. So try to create a copy of the array after mutation:
this.iteratedData.push(newItem);
this.iteratedData = this.iteratedData.slice();
OR:
constructor(private changeDetectorRef: ChangeDetectorRef)
And you can call a method markForCheck to trigger a changeDetection:
this.iteratedData.push(newItem);
this.changeDetectorRef.markForCheck();
Here is the example:
Component:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular 5';
data:any = [];
ngAfterViewInit(){
this.changeDate();
}
ngForAfterInit(valuue) {
alert('FOR LOOP COMPLETED : '+ valuue);
}
ChangeDate(){
let i = 0;
setInterval(()=>{
this.data=[];
for(var j=0; j<10; j++){
this.data.push("TEST DATA "+ j+" SET AT : "+i);
};
i+=1;
},7000);
}
}
html:
<div *ngFor="let item of data; let last=last;">
{{item}} {{last? ngForAfterInit(item) :''}}
</div>
SetInterval is like your API which will assign data.This is working for me
https://stackblitz.com/edit/pokemon-app-4n2shk
This question already has answers here:
Angular 4/5/6 Global Variables
(6 answers)
Closed 3 years ago.
im creating the window variable over and over again how can i declare it only once ?
i tried adding it to the constructor but that didn't work.
import { Component } from '#angular/core';
import { ElectronService } from 'ngx-electron';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.sass']
})
export class AppComponent {
title = 'ae-test';
constructor(
private _ES: ElectronService,
) {}
minWindow() {
const window = this._ES.remote.getCurrentWindow();
window.minimize();
}
fullscreenWindow() {
const window = this._ES.remote.getCurrentWindow()
if (window.isFullScreen() == true) {
window.setFullScreen(false);
} else {
window.setFullScreen(true);
}
}
closeWindow() {
const window = this._ES.remote.getCurrentWindow();
window.minimize();
}
}
Just create a shared singleton service
#Injectable()
export class GlobalService {
private _data = {value:0};
getData(){
return this._data; // get ref of the data object 👀
}
}
notice that every time you ask for data you got the same object so
there is need to create a property in the component body unless you
want to display the object in the template
shared or singleton service is just a service add to AppModule or root module providers list
#NgModule({
...
providers: [GlobalService]
})
export class AppModule { }
if you want to render any data from the data object you need to create a property in the component body a,b to hold a reference of the object.
export class AComponent implements OnInit {
data;
constructor(public _g:GlobalService) { }
ngOnInit() {
this.data = this._g.getData()
}
}
in case you just want to change the data c component
export class CComponent {
data;
constructor(public _g:GlobalService) { }
reset() {
const data = this._g.getData(); // 🌟
data.value = 0;
}
inc(){
const data = this._g.getData(); // 🌟
data.value +=10;
}
}
in the global service getData return a reference to _data object not a new object every time
stackblitz demo
Define a new property in your component and assign it once in your constructor (or even better ngOnInit if you implement the OnInit lifecycle hook):
private window: any;
constructor(private _ES: ElectronService) {
this.window = this._ES.remote.getCurrentWindow();
}
add window variable to component nad set it in the ngOnInit hook:
this.window = this._ES.remote.getCurrentWindow();
just use a global variable
import { Component } from '#angular/core';
import { ElectronService } from 'ngx-electron';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.sass']
})
export class AppComponent {
title = 'ae-test';
window = null;
constructor(
private _ES: ElectronService,
) {
this.window = this._ES.remote.getCurrentWindow();
}
minWindow() {
this.window.minimize();
}
fullscreenWindow() {
if (this.window.isFullScreen() == true) {
this.window.setFullScreen(false);
} else {
this.window.setFullScreen(true);
}
}
closeWindow() {
this.window.minimize();
}
}
you can initialise window in the ngOnInit function too
You can solve your problem by this answer. So it's a possible repeated question:
Angular Globals variables
I have an empty object array like this groupList:any = {} and now I want to push an object into it. I am trying to name and description as an object.
It is not an array, array is represented like [] , probably you need
groupList:any = [];
and then,
this.groupList.push({name:'you',description:'what is array'});
app.component.ts
declare var require: any;
import { Component } from '#angular/core';
import { OnInit } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent{
groupList:any = [];
arrayVal:any;
currentVal : any;
title = 'projectchart';
public array = [{"id":1},{"id":3},{"id":5}];
getPrev(){
this.array.forEach((item, index) => {
this.groupList.push(item.id);
});
console.log(this.groupList);
}
}
app.component.html
<button (click) ="getVal()">Previous Value</button>
Any idea why I can get hold of all child component properties but not any of its methods?
I need to call a method on the child component (without using a service or an eventEmmiter) to validate its state and return a property.
Parent
#Component({
selector: 'page-login',
templateUrl: 'login.html'
})
export class MyParent {
#ViewChild('childEl') childEl: PhoneInputComponent;
getChildValue() {
const value = this.childEl.getMyValue();
console.log(value);
console.log(this.childEl);
}
}
Child
#Component({
selector: 'phoneinput',
templateUrl: 'phoneinput.html'
})
export class PhoneInputComponent {
private onKey = new Subject<string>();
#Input() phone: string;
private errorMessage: string;
getMyValue() {
return 'hello from child';
}
}
console.log of value:
undefined
console.log of this.childEl:
PhoneInputComponent{onKey{}:Subject{}, phone:null, errorMessage:null}
no way to make getValue() available
Modify your code
#Component({
selector: 'page-login',
templateUrl: 'login.html'
})
export class MyParent {
#ViewChild(PhoneInputComponent) childEl: PhoneInputComponent;
getChildValue(){
const value = this.childEl.getMyValue();
console.log(value);
console.log(this.childEl);
}
Example:https://stackblitz.com/edit/angular-v4qqtt
I have a component like this:
import { Component, OnInit,Input } from '#angular/core';
#Component({
selector: 'topic-details',
templateUrl: './detailpane.component.html',
styleUrls: ['./detailpane.component.scss']
})
export class DetailpaneComponent implements OnInit {
#Input() topics;
myprop;
constructor() { }
assign(property,value){
property = value;
}
ngOnInit() {
}
}
And in my template:
<button (click)='assign(myprop,"some value")'>testing</button>
{{myprop}}
Take a look at the myprop property. In essence assign method has no effect! I was expecting myprop in the template to refer exactly same myprop in the component. I am beginnning to think that as soon as myprop goes out of the component inside the template, it becomes local to the template and doesn't reference the component (original) property.
Any explanation would be great!
You are assigning the value to wrong property, your property below, only exists in that function:
assign(property,value){
property = value;
}
but you want to assign it to myProp instead, which is also the variable you display in your view:
assign(property,value){
this.myProp = value;
}
Make notice of the keyword this
And if you actually have just one myProp (and not part e.g of iteration), you don't need to pass it to the function, just the new value:
<button (click)='assign("some value")'>testing</button>
assign(value){
this.myProp = value;
}
showPane is a primitive, thus is immutable.
This is more a javascript thing than an angular 2 issue.
you can either set it the template (my favorite)
(click)='showPane = !showPane'
or use an object
//in class
flagsCollection = {showPane:false}
toggle(flag){
this.flagsCollection[flag] = !this.flagsCollection[flag];
}
// in template
(click)='toggle("showPane")'
Your toggle method change locally the flag parameter. If you want to update showPane you could try this :
#Component({
selector: 'topic-details',
templateUrl: './detailpane.component.html',
styleUrls: ['./detailpane.component.scss']
})
export class DetailpaneComponent implements OnInit {
#Input() topics;
showPane = false;
constructor() { }
toggle(){
this.showPane = !this.showPane;
}
ngOnInit() {
}
}
<div class="col-md-12 list-group topics" [ngClass]="{'topics-small':showPane}" >
<a class="list-group-item cursor-pointer"
*ngFor='let topic of topics'
(click)='toggle()'
>{{topic.name}}</a>>
</div>