Angular8 passing #input class object in child component then access this value in parent component not work - angular6

Below are child component code :
#Input('enableAutoshutdown') enableAutoshutdown: EnableAutoshutdownObject;
#Output() data = new EventEmitter<EnableAutoshutdownObject>();
sendData() {
let enableAutoshutdownObject = new EnableAutoshutdownObject();
enableAutoshutdownObject.ShutdownTime = this.fgEnbleAutoShutdownVm.value.ShutdownTime;
this.enableAutoshutdown = enableAutoshutdownObject;
this.data.emit(this.enableAutoshutdown);
}
below are parent component code:
<app-azure-support-enable-auto-shutdown [isEnableAutoshutdown]="isEnableAutoshutdown" [(enableAutoshutdown)]="enableAutoshutdown" ></app-azure-support-enable-auto-shutdown>
.ts
ngOnInit(): void {
console.log(this.enableAutoshutdown)
}
But getting undefined.i want to pass value from child component to parent with object and using two way data binding I am following some document but not working

<app-azure-support-enable-auto-shutdown [isEnableAutoshutdown]="isEnableAutoshutdown" (enableAutoshutdown)="enableAutoshutdown($event)" >

Related

#input is not working for Api response value- angular

I am using two components parent component and child component and I want to pass the value from parent to child and I used #input method
------------------------------When I hardcoded the value----------------------------------
PARENT COMPONENT
ts file
ngOnit(){
this.name='JOB';
}
html file
<app-parent [name]='name'></app-parent>
CHILD COMPONENT
#input name: any
ngOninit(){
console.log(this.name)
}
------------------------------ When I passed value from Api----------------------------
PARENT COMPONENT
ts file
ngOnit(){
getMethod();
}
getMethod(){
this.apiService.getAll(data)
.subscribe(data => {
if (data.success) {
this.name=data.data.name
}
});
}
}
html file
<app-parent [name]='name'></app-parent>
CHILD COMPONENT
#input name: any
ngOninit(){
console.log(name)
}
Here when console, the value is undefined
Why its not working .Can anybody help me ??
....
#Input name: any; // change the #Input decorator. You used a lowercase "i"
....
ngOninit(){
console.log(this.name) // access the class property using "this"
}
if you are using input with I capital.
try with this snippet.
#Input() set name(name: string) {
if (name) {
this._name= name;
}
}
_name: string
Now console this._name on ngoninit, even then if it will not work, you have to use next life cycle hook (afterviewinit).
This will make name a property and set it every time it change.
Thanks

How would you set getElementById when retrieving data from a different angular component?

I am working in Angular 6. I am trying to basically print a JS variable. The trouble is that the variable is created in one component but I am trying to print it in another.
What I did was create a service that would share that varaible with the new component. I then try to use getElementById to set the html id.
My more-information.html looks like:
<br>
<div>
<div>
<h2>User <span id="user"></span></h2>
</div>
I have a results component that does this:
this._informationServ.saveData(userArray);
this._informationServ.saveUser(user);
My information service does this:
export class InformationService {
ourUser: string;
userData = [];
constructor() { }
saveUser(user){
this.ourUser = user;
}
saveData(someArray){
this.userData = someArray;
}
getUser(){
return this.ourUser;
}
getData(){
return this.userData;
}
}
And then finally I have a MoreInformation componenent that looks like:
export class MoreInformationComponent {
finalData = [];
ourUser: string;
constructor(private _informationServ: InformationService) {
this.finalData = this._informationServ.getData();
this.ourUser = this._informationServ.getUser();
}
ngOnInit() {
}
}
I have tried using the line
document.getElementById("user").innerHTML = this.ourUser;
in the constructor of the MoreInformation Comp., which gave me the error:
TypeError: Unable to set property 'innerHTML' of undefined or null reference
I then tried creating a function onCall() inside the MoreInformation Comp. that does the getElementbyId line and call it in the constructor, which also did not work.
I also just tried doing something like
<br>
<div>
<div>
<h2>User {{ourUSer}}</h2>
</div>
But only User showed up
Would anyone have an idea on how to best do this?
Instead of setting the value like this:
document.getElementById("user").innerHTML = this.ourUser;
You can declare a variable in the component where you want to render the value and set it to this.ourUser value:
yourVariable = this.ourUser;
And then use it to show the value in your template:
<h2>User <span id="user">{{ yourVariable }}</span></h2>

Angular: How to call function after the component got the Input data

I have a parent and child component. In the parent I am searching for a user and give the userId via #Input to my child component. This is working.
After my child component is getting the value I want to call a function so that I am getting the card from the user back. How do I do this? I always getting a card is undefined error.
<p (show)="serachForCard()">
User: {{userId}}
Card: {{card.id}}
</p>
My Idea was to call a function but it is still not working.
Function in my ts file:
serachForCard() {
this.cardService.getCardByUserId(this.userId)
.subscribe(
(data: Card) => this.card= data
)
}
Implement OnChanges interface inside your child component and call your function from ngOnChanges method.
#Component({
...
})
export class MyComponent implements OnChanges {
#Input() someInput: string;
ngOnChanges(): void {
// do something with this.someInput
}
}
Documentation: OnChanges
A lifecycle hook that is called when any data-bound property of a directive changes. Define an ngOnChanges() method to handle the changes.

Cannot open form in child from parent component - 'cannot read property xxx'

Scenario: I have a list of companies that each have an array of projects as one of their variables. I will display the list of companies in the parent component/html, and only when clicking on their corresponding 'open' does a child component open to display the list of projects for that company. This list is a FormArray that is editable.
I created this FormArray example as the standalone projects component to interact and perform CRUD operations with example data.
My goal now is to open the form as a child component when I click the 'open' button on each individual company as in THIS stackblitz.
In the example it appears that this.setData(); within the constructor is causing the upset.
I have found through experimentation that, by commenting this line out causes the app not to crash, but of course the FormArray will not be loaded when I click the company 'open' button. However, I have also found that writing {{company.name}} in the child component DOES output the company details in the child, so it shows data is going through correctly.
I just cannot understand what is going wrong?
Try ngDoCheck() lifecyle hook
A lifecycle hook that invokes a custom change-detection function for a
directive, in addition to the check performed by the default
change-detector.
ngDoCheck() {
this.setData();
}
The problem lies in this.setData() call inside SubForm class constructor.
You never checked for null/undefined data. So, initially when the component loads, this.company is undefined. Hence, name variable will be assigned undefined value.
So, when program tries to access the value of this.company in the below line, it gives error:
setData() {
let control = <FormArray>this.myForm.controls.data;
control.push(this.fb.group({
name: this.company.name,
...
}));
}
Solution:
Add null/undefined check for this.company before calling this.setData():
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
data: this.fb.array([])
})
if(!isNullOrUndefined(this.company)){
this.setData();
}
console.log(this.company)
}
As I tried on the StackBlitz, few changes to be done to get it working:
You have to access the #Input variable in ngOnInit() by implementing an OnInit interface.
Parent Component .TS file:
isOpened : boolean = false; // one local variable of type boolean to open child compo
openInfo(company) {
this.isOpened = !this.isOpened;
this.openCompany = company;
this.open=true;
}
Parent Component HTML Code:
<mat-card *ngFor="let data of DATA">
{{data.name}}
<button mat-raised-button (click)="openInfo(data)">open</button>
</mat-card>
<div *ngIf="isOpened">
<subform [company]="openCompany"></subform>
</div>
Child Component .TS Code:
Import this:
import {
Component, OnInit, Input
} from '#angular/core';
and Component class:
export class SubForm implements OnInit {
#Input() company: any;
myForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.myForm = this.fb.group({
data: this.fb.array([])
})
console.log(this.company);
this.setData();
}
}
A working example

Angular2 binding throws an error "Expression has changed after it was checked"

As i having parent and child component as follows,
Child Component (RWTaxComponent)
import { Component, OnInit, Input, Output, EventEmitter } from '#angular/core';
#Component({
selector: 'rw-tax',
templateUrl: 'rw.tax.component.html'
})
export class RWTaxComponent implements OnInit {
#Input() hsn: string = '';
#Input() srno: string = '';
#Input() taxPercent: number;
#Output() taxPercentChange: any = new EventEmitter();
constructor(
) { }
ngOnInit() {
}
ngOnChanges(event) {
console.log('HSN:: '+this.hsn);
console.log('SRNO:: '+this.srno);
if (this.hsn && this.srno) {
// Doing my logic here to find taxPercent
this.taxPercentChange.emit(this.taxPercent);
}
}}
Child component template (rw.tax.component.html) is,
<p>{{taxPercent | number:'1.2-2'}}</p>
And i invoked the above child component in my parent component as follows,
<rw-tax [(hsn)]="lineItem.hsn" [(srno)]="lineItem.srno" [(taxPercent)]="lineItem.taxPercent"></rw-tax>
I want to change taxpercent whenever hsn/srno is changed, these hsn/srno is not changed in RWTaxComponent itself, it is changed by parent component.
So i used ngOnChanges() event to detect that hsn/srno is changed and it getting invoked when ever i change hsn and srno in my parent component.
But the problem is after doing my logic to find taxpercent am trying to update the value in parent component by this.taxPercentChange.emit(this.taxPercent); and getting error "Expression has changed after it was checked"
Am i wrongly understood the Angular2 lifecycle ?
Please suggest a right way to do it...
This issue occurs when there is a change in input of the component and on that change if we are trying to change or emit any property.
Solution 1:
try promises resolve the changes and in then block emit the output event.
Solution 2 : (may not work)
Try setTimeout method on emitting the value