1

I encountered a wizard problem in angular5. I have one component parent which send data binding in a child component, but the data binded are well display in child html but not in the child component.

Parent Component

@Component({
  selector: 'app-element',
  templateUrl: '../templates/app.element.component.html',
})
export class AppElementComponent implements OnInit {

  titles: {} = {};

  constructor() {}

  ngOnInit(): void {
    // Details
    this.restService.postDb('url')
      .subscribe(response => {
         this.titles = response.title;
         // this.titles = { 'menu1': 'something', 'menu2': 'somethingelse'}
      });
  }

}

Parent Template

  <div>
    <app-panel [titles]="titles"></app-panel>
  </div>

Child Component

@Component({
  selector: 'app-panel',
  templateUrl: '../templates/app.panel.component.html',
})
export class AppPanelComponent implements OnInit {

  @Input() titles;

  constructor() {}

  ngOnInit() {
    //I put a timeout just to wait the binding
    setTimeout(function() {
      console.log(typeof this.titles);
      console.log(this.titles);
      }, 5000);
  }

}

Child Template

<pre>{{ titles | json}}</pre>
<pre>{{ titles.keys | json}}</pre>

In the child template, I have the first pre with the titles data, but the second pre doesn't work. And in the child component, the both console log return undefined. I don't understand why values of same variable are different in template and component.

Thanks.

1

2 Answers 2

4

In your code below this refers to the anonymous function, not to the class.

ngOnInit() {
    //I put a timeout just to wait the binding
    setTimeout(function () {
        console.log(typeof this.titles);
        console.log(this.titles);
    }, 5000);
}

Use arrow instead function to keep the reference as follow:

ngOnInit() {
    //I put a timeout just to wait the binding
    setTimeout(() =>  {
        console.log(typeof this.titles);
        console.log(this.titles);
    }, 5000);
}

By the way, to avoid using setTimeout, you can use the native Angular method ngOnChanges. It is called whenever an input is changed (see https://angular.io/guide/lifecycle-hooks).


The code titles.keys is trying to access to the value of propertie keys but you have no propertie keys in your object.

If you want to get an array of the keys of your object, do something like this Object.keys(this.titles) and you will get the array ['menu1', 'menu2'].

Note that if you want to use Object.keys in the template, you must beforehand bind it as follow:

@Component({
  selector: 'app-panel',
  template: `
    <pre>{{Object.keys(titles) | json}}</pre>
  `
})
export class AppPanelComponent implements OnInit {
  @Input() titles;
  Object = Object;
}
Sign up to request clarification or add additional context in comments.

3 Comments

OK thanks for the arrow function. Indeed I have now the good data. Yes I want to get keys of titles, that is to say : ['menu1', 'menu2']. Why there is no keys properties in the object ?
Moreover, when I console.log(Object.keys(this.titles)) I have well the ['menu1','menu2']. So why it's different in the template ?
In your template you are not calling Object.keys(this.titles). I edited my template since i understood what you tried to achieve.
1

In your first pre you are accessing the whole object, but in the second pre you are trying to access to a property called keys in your titles object, but this properties doesn't exist (it only has two properties called 'menu1' and 'menu2').

In case you want to access to the keys of the object:

Object.keys(titles)

2 Comments

I think what he tries to accomplish is to get all the keys of the titles object in a list like ['menu1', 'menu2'] and not 'give me the property named keys'
Yes exactly @GlennVanSchil !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.