0

I am trying to create a CRUD application that works a bit like a blog. I have all of the create, read, update, and delete functions working. I want to display only one object's data (example: title, description) based on the ID of the object which is part of the route (localhost:4200/route/0).

I can get the data to display the way I want using <input [(ngModel)]"articles.title">, but not using ngFor on <h1> or any other tag.

app-routing-module.ts

{ path: 'article/:id', component: ArticleComponent}

db.json

"articleInfo": [
    {
      "id": 0,
      "title": "Marinara Pasta",
      "category": "Italian",
      "author": "Sample",
      "date": "06/11/2019",
      "description": "A classic Italian dish. Quick, easy, and ready to eat in only 15 minutes.",
      "image": "/assets/sample.png"
    }
]

data.service.ts

baseUrl:string = "http://localhost:3000";

getData(id: number): Observable<Data> {
  return this.http.get<Data>(this.baseUrl + '/articleInfo/' + id)
}

article.component.ts

export class ArticleComponent implements OnInit {

  id = this.actRoute.snapshot.params['id'];
  articles: any = [];

  constructor(private dataService: DataService, public actRoute: ActivatedRoute, public router: Router) { }
  loadIdData() {
    return this.dataService.getData(this.id).subscribe(data => {
      this.articles = data;
    })
  }

  ngOnInit() {
    this.loadIdData();
  }

}

article.component.html

<div *ngFor="let info of articles">
      <h2> {{info.title}} </h2>
      <h6> {{info.description}}</h6>
</div>

I get ERROR and ERROR CONTEXT in ArticleComponent.ngfactory.js.

2 Answers 2

1

You can update your article.component.ts to:

export class ArticleComponent implements OnInit {
  id;
  articles: Observable<any[]>;

  constructor(private dataService: DataService, public actRoute: ActivatedRoute, public router: Router) { }

  ngOnInit() {
    this.id = this.actRoute.snapshot.params['id']
    this.loadIdData();
  }

  loadIdData() {
    this.articles = this.dataService.getData(this.id);
  }

}

and article.component.html to:

<div *ngFor="let info of articles | async">
  <h2> {{info.title}} </h2>
  <h6> {{info.description}}</h6>
</div>

The issue appears to be regarding the way you've declared the id property- actRoute is only defined after the constructor has run, which happens after the properties of the class are accessed. So when your loadIdData function runs this.id is likely undefined. For more info see Angular Lifecycle Docs

Note: the | async is just some sugar, and isn't really required. You can retain your code and just update the value of the id in the constructor or ngOnInit. Here's an article explaining the async pipe

Sign up to request clarification or add additional context in comments.

1 Comment

Hi, thanks for your reply. Unfortunately, this didn't solve my issue. In my original code, I am able to show the proper data using <input [(ngModel)]="articles.title">. Your updated code isn't showing anything with ngFor or ngModel. Could the issue be something else?
0

Figured out where I was going wrong. ngFor is not the correct way to display one set of data. It is expecting multiple sets and as a result does not display anything on the page. What worked for me was pulling the info from articles: any = []; in my article.component.ts like so:

<h1> {{articles.id}} </h1>
<h2> {{articles.title}} </h2>
<h6> {{articles.description}} </h6>

For a far better explanation of why this works, please see angular.io documentation on displaying data.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.