Issue
I have the app.component, the post-create.component and the post-list.component .
the app.component.html looks like this:
app.component.html
<app-header></app-header>
<main>
<app-post-create (postCreated)="onAddedPost($event)" ></app-post-create>
<app-post-list [posts]="storedPosts" ></app-post-list>
</main>
the post-list.component.ts looks like this
post-list.component.ts
import { Component, Input } from '@angular/core';
import { Post } from '../post'
@Component({
selector: 'app-post-list',
templateUrl: './post-list.component.html',
styleUrls: ['./post-list.component.css']
})
export class PostListComponent {
@Input() posts:Post[] = [];
}
the post-create.component.ts looks like this
post-create.component.ts
import { sharedStylesheetJitUrl } from '@angular/compiler';
import { Component, EventEmitter, Injectable, Output, OutputDecorator } from '@angular/core';
import { Post } from '../post'
@Component({
selector: 'app-post-create',
templateUrl: './post-create.component.html',
styleUrls: ['./post-create.component.css']
})
export class PostCreateComponent {
enteredContent='';
enteredTitle='';
@Output() postCreated: EventEmitter<Post> = new EventEmitter<Post>();
onAddPost(){
const post={title:this.enteredTitle,content:this.enteredContent};
this.postCreated.emit(post);
}
}
and the app.component.ts looks like this
app.component.ts
import { Component, Output,Input } from '@angular/core';
import { Post } from '../app/posts/post';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
storedPosts: Post[] = [];
onAddedPost(post:Post){
this.storedPosts.push(post);
}
}
the problem is that when I press add post it wont show the new post.
any ideas?
edit: also my post.create.component.html looks like this
post.create.component.html
<mat-card>
<mat-form-field>
<input matInput type="text" [(ngModel)]="enteredTitle">
</mat-form-field>
<mat-form-field>
<textarea matInput rows="6" [(ngModel)]="enteredContent"></textarea>
</mat-form-field>
<button mat-raised-button
(click)="onAddPost()">Save post!</button>
</mat-card>
and the post-list.component.html looks like this:
<mat-accordion multi="true" *ngIf="posts.length>0" >
<mat-expansion-panel *ngFor="let post of posts">
<mat-expansion-panel-header>
{{post.title}}
</mat-expansion-panel-header>
{{post.content}}
</mat-expansion-panel>
</mat-accordion>
<p class="mat-body-1" *ngIf="posts.length <=0">no posts added yet</p>
Solution
Angular’s @Input
would only recognize the changes to it’s variables if the underlying reference has been adjusted. Since the Array#push
doesn’t affect it’s holding variable, they might not be detected. Instead of Array#push
you could append new elements using the spread syntax.
Try the following
onAddedPost(post:Post){
this.storedPosts = [...this.storedPosts, post];
}
Check @Input
change using ngOnChanges()
hook
You could check if the changes are detected in the child component using the ngOnChanges
hook. Try the following
import { Component, Input, OnChanges, SimpleChanges } from "@angular/core";
import { Post } from "../post";
@Component({
selector: "app-post-list",
templateUrl: "./post-list.component.html",
styleUrls: ["./post-list.component.css"]
})
export class PostListComponent implements OnChanges {
@Input() posts: Post[] = [];
ngOnChanges(changes: SimpleChanges) {
if (changes.posts && changes.posts.currentValue) {
console.log(changes.posts.currentValue);
}
}
}
I’ve modified your Stackblitz.