muhumuza amb
muhumuza amb

Reputation: 11

My data from child component is not showing up in the parent component

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

Answers (3)

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

MoxxiManagarm
MoxxiManagarm

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:

  • Hide CardComponent until projData is defined (@if, ngIf)
  • Access mydata null safe (myData?.title)
  • With the help of resolveJsonModule compiler option, you could import the json directly instead of using the http module, which leads to a sync behavior instead of async

Upvotes: 0

SergeyChe
SergeyChe

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

Related Questions