Reputation: 102
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>
Upvotes: 0
Views: 114
Reputation: 1
Try
onPostAdded(posts) {
this.Storedposts.push(posts)
}
instead of
onPostAdded(post) {
this.Storedposts.push(post)
}
Upvotes: -1
Reputation: 31115
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];
}
@Input
change using ngOnChanges()
hookYou 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.
Upvotes: 2
Reputation: 18859
I think this has to do with change detection and that arrays are reference types so you have to change the location in memory that the array is stored in order for change detection to be guaranteed to run.
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){
// the line below does not change the location of the array in memory and
// therefore change detection doesn't run
// this.storedPosts.push(post);
// update this way, spread the old posts and append the new post
// and this will assign storedPosts in a new location in the array.
this.storedPosts = [...this.storedPosts, post];
}
}
Upvotes: 1