Reputation: 11
I have a json file, then I create a card component where that data would be displayed, then I create a parent component and template where I want to iterate through the data and generate a number of cards. However, the data doesn't show up when I call it through the card component.
Here is the Card component
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.css']
})
export class CardComponent implements OnInit {
@Input() mydata!: {title: string, description: string};
constructor() { }
ngOnInit(): void {
}
}
Here is the Card template for that card component;
<span class="flex gap-4 items-center">
<svg class="iconsboxed" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path d="M13.5 3a.5.5 0 0 1 .5.5V11H2V3.5a.5.5 0 0 1 .5-.5zm-11-1A1.5 1.5 0 0 0 1 3.5V12h14V3.5A1.5 1.5 0 0 0 13.5 2zM0 12.5h16a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 0 12.5"/>
</svg>
<span class="text-lg">{{mydata.title}}</span>
</span>
<p class="text-sm text-gray-400 py-4">{{mydata.description}}
</p>
Now, this is the parent component;
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-projects',
templateUrl: './projects.component.html',
styleUrls: ['./projects.component.css']
})
export class ProjectsComponent implements OnInit {
projData!: any
constructor(private http: HttpClient) {
}
ngOnInit(): void {
this.http.get<any>('../assets/data.json').subscribe(mydata =>{
this.projData = mydata;
console.log(this.projData)
})
}
}
And this is the parent template;
<div class="flex items-center justify-center bg-background2 h-full w-full mb-0 text-gray-100 ">
<div class="max-w-6xl mx-auto ">
<header class="flex flex-col items-center justify-center">
<p class="text-6xl font-bold pb-[1rem]">Solutions I have crafted</p>
<p class="text-lg pb-[2rem] text-center ">A list of the projects that I have worked on ranging from multiple languages and frameworks.</p>
</header>
<main class="grid grid-cols-3" >
<div class="flex flex-col border-[1px] border-accent px-6 py-8 rounded-md" *ngFor= "let proj of projData">
<app-card [mydata]="projData"></app-card>
</div>
</main>
</div>
</div>
However my data doesnt show up. I'm not sure what is going on.
This is the sample data.json file structure.
[
{
"title": "Lorem Ipsum",
"description": "The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here,.",
},
{
"title": "Lorem Ipsum",
"description": "The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here,.",
},
{
"title": "Lorem Ipsum",
"description": "The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here,.",
},
]
When I move the array into ProjectComponent, it shows up but when I use the card component, it doesn't show up. I am using Angular 14.
Here is the git repo should someone need to see the entire code; https://github.com/muhumuzaa/angularhumber/tree/projs Thanks.
Upvotes: 0
Views: 134
Reputation: 16
It`s also possible to use async pipe for work with asunchronose data:
declare Observable in the component:
public projData$ = this.http.get<any>('../assets/data.json');
Than in your template use async pipe :
<div *ngIf="projData$ | async as cards; else noCards">
<div class="flex flex-col border-[1px] border-accent px-6 py-8 rounded-md"
*ngFor= "let card of cards">
<app-card [mydata]="card"></app-card>
</div>
</div>
<ng-template #noCards>There no cards _)</ng-template>
Use [official angular documentation]1 to discover more about angular pipes!
Thanks!
Upvotes: 0
Reputation: 9134
http.get
is still an async method. That means, that projData
is undefined for a short moment until the subscription callback was executed, which leads to errors, since you want to access that undefined value in CardComponent
.
There are several solutions. Just to name some:
@if
, ngIf
)mydata
null safe (myData?.title
)resolveJsonModule
compiler option, you could import the json directly instead of using the http module, which leads to a sync behavior instead of asyncUpvotes: 0
Reputation: 113
mistake is here
<app-card [mydata]="projData"></app-card>
replace projData
to proj
It will work.
<app-card [mydata]="proj"></app-card>
Upvotes: 0