[Fixed] New content now showing up when added (angular)

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.

Leave a Reply

(*) Required, Your email will not be published