Trying to update the carType value from another component.Updated value only working inside the callFun fucntion. Not able to get outside of the callFun function. I am trying to get the updated value inside callFlag function. But it is not working. So, how to resolve this issue.
compone.component.html:
export class ComponeComponent implements OnInit {
constructor() {}
carType = false;
ngOnInit() {}
callFun(flag: any) {
this.carType = flag;
console.log(this.carType);
}
callFlag() {
alert(this.carType);
}
}
compthree.component.html:
export class CompthreeComponent implements OnInit {
constructor(public onecomp: ComponeComponent) {}
ngOnInit() {
this.onecomp.callFun(true);
}
}
Demo: https://stackblitz.com/edit/angular-ivy-dxk3m9?file=src/app/compone/compone.component.ts
CodePudding user response:
You're injecting "ComponeComponent", but this is not related to the component you have in your application. This is the reason you can use the functions of the ComponentComponent.
You only can "reach" the child, content,.. of a component (not a "grandchild"). If you want to make directly you should use a service that inject in the component you want. One of them emit an event and another one listen the Subject, see the docs
If ComponentComponent was a directly child you can use Viewchild
//in CompthreeComponent
@ViewChild(ComptwoComponent) twocomp:ComptwoComponent
//in ComptwoComponent
@ViewChild(ComponeComponent) onecomp:ComponeComponent
So you can do in CompthreeComponent some like
ngAfterViewInit() {
this.twocomp.onecomp.callFun(true);
}
See that, you should use ngAfterViewInit (only if use {static:true} in ViewChild -and you can only use if your components are always (e.g. they are not under a *ngIf)- you can use ngOnInit.
Your forked stackblitz
CodePudding user response:
the common way to do that is to pass value fron child to parent compo with emitter
export class ChildComponent {
@Output() $buttonClicked = new EventEmitter<boolean>();
public click(): void {
this.$buttonClicked.emit(true);
}
}
//////parent.component.html
<child-selector
($buttonClicked)=callFun($event)>
</child-selector>
//////parent.component.ts
...
export class ParentComponent {
public callFun(value: boolean): void {
this.carType = flag;
}
}
CodePudding user response:
I have forked your stackblitz project. See this.
If you define a value with @Input()
, it can be passed from parent component.
And parent html can pass value like <app-comp*** [carType]="value">
So your html and ts will be like this.
compone.component.ts
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-compone',
templateUrl: './compone.component.html',
styleUrls: ['./compone.component.css'],
})
export class ComponeComponent implements OnInit {
constructor() {}
@Input() carType = false;
ngOnInit() {}
callFun(flag: any) {
this.carType = flag;
console.log(this.carType);
}
callFlag() {
alert(this.carType);
}
}
comptwo.component.html
<app-compone [carType]="carType"></app-compone>
comptwo.component.ts
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-comptwo',
templateUrl: './comptwo.component.html',
styleUrls: ['./comptwo.component.css'],
})
export class ComptwoComponent implements OnInit {
@Input() carType = false;
constructor() {}
ngOnInit() {}
}
compthree.component.html
<app-comptwo [carType]="true"></app-comptwo>
CodePudding user response:
When there is no relation between the component you can use a service to share data between components.
Create a Subject in a service and subscribe to it in ComponeComponent
.
app.service.ts
...
carTypeChanged$ = new Subject<boolean>();
constructor() {}
getCarTypeChanged() {
return this.carTypeChanged$.asObservable();
}
setTitle(value: boolean) {
this.carTypeChanged$.next(value);
}
...
compone.compontent.ts
this.appService
.getCarTypeChanged()
.pipe(delay(0))
.subscribe((value) => {
this.carType = value;
});
Use this observable to emit the value from CompthreeComponent
.
this.appService.setCarTypeChanged(true);
I've modified your stackblitz to use services for sharing data between components.