0
votes

I am completely new to Angular, have started it last week (but I have a small basic background in programming). I am trying to build a very basic blog application, and I want to get a value from the root (app.component.ts) to my component tag(s) "app-post-list-item", located in my other component template (post-list-component.html), so that I can display it in my post list item. I have tried @Input() in various places, but the text just doesn't show up. There might be something I am missing or misunderstanding, but this is just all so intimidating and I don't know what or how to do now. I have tried to move the "post-list-item" folder inside the "post-list" one, but it doesn't work either. So, note that both "post-list" and "post-list-item" are children components of "app".

Can anyone check my code and tell me how I could make that work, please? That would be awesome. Thank you!!

This is my architecture.

app.component.html:

<div class="row">
  <div class="col-12">
    <app-post-list></app-post-list>
  </div>
</div>

app.component.ts:

export class AppComponent {  
  title = 'blogApp';  
  pub1: string = "Ma première publi"; // this is what I want to display
}

post-list.component.html:

<ul class="list-group">   
  <app-post-list-item [titrePubli]="pub1"></app-post-list-item> <!-- this is where I tell that I want to display -->
  <app-post-list-item></app-post-list-item>
  <app-post-list-item></app-post-list-item>
</ul>

post-list.component.ts:

import { Component, OnInit, Input } from '@angular/core';
@Component({
  selector: 'app-post-list',
  templateUrl: './post-list.component.html',
  styleUrls: ['./post-list.component.scss']
})

export class PostListComponent implements OnInit {
  @Input() pub1: string; // note the @Input() here
  constructor() { }
  ngOnInit(): void {  }
}

post-list-item.component.html:

<li class="list-group-item">
  <h3 style="font-size: 20px;">Titre : {{ getTitrePubli() }}</h3> <!-- this is where I want to display -->
  <h4 style="font-size: 18px;">Contenu : {{ getContenuPubli() }}</h4>
</li>

post-list-item.component.ts:

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-post-list-item',
  templateUrl: './post-list-item.component.html',
  styleUrls: ['./post-list-item.component.scss']
})

export class PostListItemComponent implements OnInit {
  @Input() titrePubli: string;
  contenuPubli: string = "C'est le bla bla bla";

  @Input() pub1: string;

  constructor() { } 

  ngOnInit(): void { }

  getTitrePubli() { return this.titrePubli; }
  getContenuPubli() { return this.contenuPubli; }
}
1

1 Answers

1
votes

The attached screenshot is not the architecture, it is the file structure of the project. And it has nothing to do with the data sharing as long the files are correctly referenced in the module and other files where they are used.

The source of the confusion here is the naming scheme. Let's look at one simple line

<app-post-list [pub1]="pub1"></app-post-list>
                 ˄       ˄
                 |       |
        @Input()         member
        variable         variable
        of post-list     of app-component

As you can see, [pub1] refers to the input variable of post-list component and pub1 on the right side refers to the member variable value ("Ma première publi" in your case).

While the above pattern isn't incorrect, if you are beginning Angular, it might serve you well to have some obvious naming patterns. For eg.,

<app-post-list [pub1Input]="pub1Value"></app-post-list>

Now there is a clear distinction between the variable names and it helps understanding better. Then you send the variable again from post-list to post-list-item component. I've modified your code to following and it works as expected.

App component

export class AppComponent  {
  title = 'blogApp';  
  pub1Value: string = "Ma première publi";
}
<div class="row">
  <div class="col-12">
    <app-post-list [pub1Input]="pub1Value"></app-post-list>
  </div>
</div>

Post list component

export class PostListComponent implements OnInit {
  @Input() pub1Input: string;

  titrePubliOne = 'title 1';
  titrePubliTwo = 'title 2';
  titrePubliThree = 'title 3';

  constructor() { }

  ngOnInit() { }
}
<ul class="list-group">   
  <app-post-list-item [titrePubli]="titrePubliOne" [pub1]="pub1Input"></app-post-list-item>
  <app-post-list-item [titrePubli]="titrePubliTwo" [pub1]="pub1Input"></app-post-list-item>
  <app-post-list-item [titrePubli]="titrePubliThree" [pub1]="pub1Input"></app-post-list-item>
</ul>

Post list item component

export class PostListItemComponent implements OnInit {
  @Input() titrePubli: string;
  @Input() pub1: string;
  contenuPubli: string = "C'est le bla bla bla";

  constructor() { }

  ngOnInit() { }
}
<li class="list-group-item">
  <h3 style="font-size: 20px;">Titre : {{ titrePubli }}</h3>
  <h4 style="font-size: 18px;">Contenu : {{ pub1 }}</h4>
</li>

Working example: Stackblitz