I've hit a roadblock with this issue that's been puzzling me for a few days now. The flow of the application goes as follows:
Call API -> Receive Response -> Display Results in Parent Component -> Pass Results from Parent to Child When a User Clicks a Result.
The challenge lies in the last step, where I'm struggling to pass a nested result from my Parent component (missionList) to my Child component (missionDetails)
When I try to access the property 'mission_small_patch' in the HTML file of the Child Component, it throws an error saying Property 'mission_small_patch' does not exist on type 'ILinks[]'
What confuses me is that simply re-saving my Interface file makes the image appear in the Child Component upon reloading the application! This inconsistency baffles me, as I know the property exists and I believe I'm accessing it correctly.
I'm at a loss trying to figure out what I might be overlooking here. Could it be related to how I display data in the Parent component using a custom pipe? I've also attempted to modify the getMission() method in the parent to map the values like this, but still no luck:
getMission():void{
this.service.subscribe((resp:any)=>{
this.mission_patch_small = resp.map(r => r.links)
})
}
The external API response provides me with a nested object, specifically targeting the links: mission_patch_small
"flight_number": 1,
"mission_name": "FalconSat",
"launch_failure_details": {
"time": 33,
"altitude": null,
"reason": "merlin engine failure"
},
"links": {
"mission_patch": "https://images2.imgbox.com/40/e3/GypSkayF_o.png",
"mission_patch_small": "https://images2.imgbox.com/3c/0e/T8iJcSN3_o.png",
"reddit_campaign": null,
"reddit_launch": null,
"reddit_recovery": null,
"reddit_media": null,
"presskit": null,
"article_link": "https://www.space.com/2196-spacex-inaugural-falcon-1-rocket-lost-launch.html",
"wikipedia": "https://en.wikipedia.org/wiki/DemoSat",
"video_link": "https://www.youtube.com/watch?v=0a_00nJ_Y88",
"youtube_id": "0a_00nJ_Y88",
"flickr_images": []
},
Despite creating an interface for the received data, including an additional field mission_patch_small, I can't seem to access this property. I even tried changing the type of mission_patch_small to mission_patch_small : string[] without success. I made this change for mapping the links URL in the getMission() method mentioned above.
export interface IMission {
mission_name: string;
launch_year: string;
details: string;
mission_patch_small: string;
links: ILinks[];
}
export interface ILinks {
mission_patch_small: string[];
}
This is how I fetch data using HttpClient & RxJs Observables
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { IMission } from '../models/mission';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class SpacexapiService {
baseURL: string = 'https://api.spacexdata.com/v3/launches';
constructor(private http: HttpClient) {}
getMission(): Observable<IMission[]> {
return this.http.get<IMission[]>(this.baseURL);
}
}
This snippet shows my missionList.component.ts file
import { Component, OnInit } from '@angular/core';
import { IMission } from '../models/mission';
import { SpacexapiService } from '../network/spacexapi.service';
@Component({
selector: 'app-missionlist',
templateUrl: './missionlist.component.html',
styleUrls: ['./missionlist.component.css'],
})
export class MissionlistComponent implements OnInit {
missionList!: IMission[];
selectedMission!: IMission;
constructor(private service: SpacexapiService) {}
getMission(): void {
this.service.getMission().subscribe((resp: any) => {
this.missionList = resp;
console.log(resp);
});
}
onSelect(mission: IMission): void {
this.selectedMission = mission;
}
ngOnInit(): void {
this.getMission();
}
}
Data Displayed in The Parent Component missionList
This section works fine: The nested data from links displays without issues here
<ul class="missions"
*ngIf="missionList">
<li *ngFor="let mission of missionList | keys"
(click)="onSelect(mission)"
<span>{{mission.mission_name}}</span> -- {{mission.launch_year}}
<p>{{mission.details}}</p>
<aside><img [src]="mission?.links?.mission_patch_small" /></aside>
</li>
</ul>
<app-missiondetails>[mission]="selectedMission"></app-missiondetails>
Keys Pipe
export class KeysPipe implements PipeTransform {
transform(value: any, args?: any[]): any {
let keys: any = Object.keys(value),
data: any = [];
keys.forEach((key: any) => {
data.push(value[key]);
});
return data;
}
Child Component missionDetails
export class MissiondetailsComponent implements OnInit {
@Input() mission!: IMission;
constructor() {}
ngOnInit(): void {}
}
Finally, Here's How I Attempt to Display Data in the Child and Encounter the Error.
<ul *ngIf="mission">
<li><span>{{mission.mission_name}}</span> {{mission.launch_year}}
<p>{{mission.details}}</p>
<p>{{mission.links | json}}</p>
<aside><img [src]="mission?.links?.mission_small_patch" /></aside>
</li>
</ul>