Farrukh Waheed
Farrukh Waheed

Reputation: 2193

Angular: @input doesn't seems to be working


I have just started learning the Angular and begin by following this youtube tutorial. But, it looks like that @Input is not working here. Here is the model class to store data:

Todo.ts:

export class Todo {
  id: number;
  title: string;
  complete: boolean;
  optional?: string;
}

Todos component along with data: todos.component.ts

import { Component, OnInit } from '@angular/core';
import {Todo} from '../../models/Todo';

@Component({
  selector: 'app-todos',
  templateUrl: './todos.component.html',
  styleUrls: ['./todos.component.css']
})
export class TodosComponent implements OnInit {
  todos: Todo[];

  constructor() { }

  strTest = 'A test string';

  ngOnInit(): void {
    this.todos = [
        {
          id: 1,
          title: 'One',
          complete: false
        },
        {
          id: 2,
          title: 'two',
          complete: true,
          optional: 'an optional item'
        },
        {
          id: 3,
          title: 'three',
          complete: false
        }

    ];

  }

}

todos.component.html

<p>todos from local class</p>
<!-- Working -->
<ul *ngFor='let td of todos'>
  <li>{{td.title}}</li>
</ul>


<p> From todo-item class</p>
<!-- Not Working -->
 <app-todo-item *ngFor="let todo of todos"  [todos]="todo" > </app-todo-item>

Following is where selector app-todo-item is defined and @Input from Todo is performed:

todo-item.component.ts

import { Component, OnInit, Input} from '@angular/core';
import { Todo } from 'src/app/models/Todo';

@Component({
  selector: 'app-todo-item',
  templateUrl: './todo-item.component.html',
  styleUrls: ['./todo-item.component.css']
})
export class TodoItemComponent implements OnInit {

  @Input() todos: Todo;

  constructor() {
    console.log(this.todos.title);
  }

  ngOnInit(): void {
  }

}

And todos-item.component.html, which is supposed to display the values

 <div>
  <p> {{ todos.title }}  </p>

</div>

I'm not able to find the missing piece here. Please help.. Thanks

Upvotes: 2

Views: 2270

Answers (2)

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24406

According to the Angular Docs, ngOnChanges is used to “Respond when Angular (re)sets data-bound input properties. The method receives a SimpleChanges object of current and previous property values. Called before ngOnInit() and whenever one or more data-bound input properties change.” , so a good place to start check the data will be ngOnInit life cycle hook

export class TodoItemComponent implements OnInit {

  @Input() todos: Todo;

 constructor() {
  /*
  Don't access, initialize, modify at constructor. 
  Misko Hevery, Angular team lead, explains why you should avoid complex constructor logic.
  Link --> http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/
  */

  //console.log(this.todos.title);                                     
 }    

 ngOnInit(): void {
    console.log(this.todos.title);
 }

}

read this exploring angular lifecycle hooks onchanges

Upvotes: 3

julianobrasil
julianobrasil

Reputation: 9357

Use the optional chaining operator in your template (todos-item.component.html). If todos is null/undefined at the beginning you can break the template rendering (cannot access title from undefined) and cause an unrecoverable javascript error that prevents anything else from working in this component. Add this:

<div>
  <!-- NOTICE THE "?" after todos -->
  <p> {{ todos?.title }}  </p>
</div>

Upvotes: 3

Related Questions