bluestHydrangea
bluestHydrangea

Reputation: 1

How to display JSON object from ID in Angular (7)

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.

Upvotes: 0

Views: 1712

Answers (2)

bluestHydrangea
bluestHydrangea

Reputation: 1

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.

Upvotes: 0

P. Moloney
P. Moloney

Reputation: 721

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

Upvotes: 1

Related Questions