#input is not working for Api response value- angular - angular6

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

Related

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

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)" >

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.

How to bind an array to the component template in Polymer 2?

I'm trying to directly bind an array to a Polymer 2 component template. It works at first but then it doesn't detect changes. I'm using this.push method in order to allow Polymer to detect the changes, but it's not working. Binding to a dom-repeat template it's OK.
Here you can find a Plunker: http://plnkr.co/edit/MWO7i7m3GB5b7Eqri1yX?p=preview
Is it possible to do what I'm trying? What am I doing wrong?
Thank you for your help
No it's not possible to bind to an array like this.
[[json(data)]] if data is an array, it won't work.
The same way for the observers :
static get observers(){
return [
'_dataChanged(data)'
]
}
This won't work.
On a direct binding, the only way for it to work is to change the complete array value with another one.
class ParentElement extends Polymer.Element {
static get is() { return "parent-element"; }
static get properties(){
return {
data: {
type: Array,
notify: true,
value: function(){
return [{name: 'first'}]
}
}
}
}
constructor() {
super();
}
json(data){
return JSON.stringify(data);
}
addChild(){
this.data = [{name: 'first'},{name: 'second'}];
}
}
customElements.define(ParentElement.is, ParentElement);
In this case above, you can see that the data array is completely replaced and it will work because it's the data object that changed.
In your case you change the content of the array, then the binding won't work.
If you want to see something, in you plunker you can change the HTML part with :
[[json(data.*)]]
Then you will see the polymer binding object that changed.
But instead of binding an array like you did, the best is to use an observer and do our action in the function :
static get observers(){
return [
'_dataChanged(data.splices)'
]
}
_dataChanged(value){
//work to do here
}
For more details you can check the polymer doc here

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