Reputation: 2193
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
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
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