Why passing custom object in @Input doesn't work?

1.4k views Asked by At

I am trying to pass a custom object through @Input. But, I'm getting null as output.

This is my child component class:

import { Component, OnInit, Input } from '@angular/core';
import { Element } from '../app.element';

@Component({
  selector: 'app-server-element',
  templateUrl: './server-element.component.html',
  styleUrls: ['./server-element.component.css']
})
export class ServerElementComponent implements OnInit {
//  @Input('srvElement') element: {type: string, name: string, content: string};    <--- This works

  @Input('srvElement') ele:Element;   <--- This doesn't work

  constructor() { }

  ngOnInit() { }

}        

This is my element class:

export class Element{
  type: string;
  name: string;
  content: string;
  constructor(type: string="", name: string="", content: string=""){
    this.type = type;
    this.name = name;
    this.content = content;
  }
}           

In parent class's html ie app.component.html, I have this(to communicate to child class):

<div class="container">
  <app-cockpit (notify)="onNotifyClicked($event)"></app-cockpit>
  <hr>
  <div class="row">
    <div class="col-xs-12">
      <app-server-element *ngFor="let serverElement of serverElements"
      [srvElement]="serverElement"></app-server-element>
    </div>
  </div>
</div>

Parent class ie app.component.ts:

import { Component } from '@angular/core';
import { Element } from './app.element';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  serverElements = [{type: 'server', name: 'Testserver', content: 'Just a test'}];
  element: {type: string, name: string, content: string};

  onNotifyClicked(e: Element){
    if(e.type==='server'){
        this.serverElements.push({
        type: 'server',
        name: e.name,
        content: e.content
      });
    } else {
        this.serverElements.push({
        type: 'blueprint',
        name: e.name,
        content: e.content
      });
    }
  }
}  

Can any one please explain to me why @Input('srvElement') ele:Element; doesn't work nor does @Input('srvElement') let ele=new Element(); (Passing my own custom object) but @Input('srvElement') element: {type: string, name: string, content: string}; just works fine??

4

There are 4 answers

0
BlackBeard On BEST ANSWER

I just found out that doing either of these two option works:

  • @Input('srvElement') element=new Element();
  • @Input('srvElement') element:Element;

NOTE: Object's name must be element as it has been used in child class's html ie server-element.component.html.

1
Kevin On

I've got an example working where I define the input as:

import {Element} from 'placeWhereThisIs';
...

@Input() srvElement: Element;
1
Pragnesh Khalas On

you need parent element which will loop and child element is your child componenet.

<div *ngFor="let serverElement of serverElements">
  <app-server-element 
       [srvElement]="serverElement"></app-server-element>  
</div>

check below line in your child component

ngOnChanges() {
   console.log(this.ele);
 }

it should work.

which ever code you write in onNotifyClicked event put that code in ngOnChanges.

because your parent component's for loop iterate after load the child component you need notification that child component input parameter is changes that's why you need ngOnChanges event.

1
Arun Redhu On

I think this may be because of Element type definition is also belongs to HTML elements. But I tried this in the plunker and worked very well. You should try after changing the name of the Element class. Here is the Plunker https://plnkr.co/edit/RSPoEEub1mtr2BC4sqxQ?p=preview