I am pretty new to Javascript and Typescript/Angular..
I am getting data / game stats from a website to make my own stats app. I have created an Interface with defined Key/Values to match the data that I want to show on my template.
The API's response that I wish to show is in the form of nested objects. Because of this, I am using Object.keys() in order to iterate through the objects, and show the result on my HTML template.
I am able to show JSON of the specific nested Object just fine. My problem is: it is showing the ENTIRE Key/Values of that Object, and not the specific key values I have defined in my Interface.
Within my HTML, I am looping through my Interface called lifeTimeStat Object.keys(lifeTimeStat)
- (also please see below for full html)
Seeing as how I need to iterate through an Object, I attempted to make my lifeTimeStat Interface an object.. Like this:
`export class CombatListComponent implements OnInit {
constructor(public combatService: CombatService) { }
lifeTimeStats: lifeTimeStat = {
headshotKills: null,
kills: null,
longestKill: null,
maxKillStreaks: null,
dailyKills: null,
weeklyKills: null,
damageDealt: null,
roadKills: null,
teamKills: null,
vehicleDestroys: null,
suicides: null,
roundMostKills: null,
dBNOs: null,
assists: null
}
ngOnInit() {
this.combatService.getCombat().subscribe(data => {this.lifeTimeStats =
data} );
}
}
`
But of course, however, I am getting this error: TypeError: Cannot read property 'keys' of undefined
.. So it seems I am not making my Interface into an Object the right way..
The only way that I can get the JSON to show in my HTML is if I instead define
Object = Object
instead of that crappy attempt of turning my Interface into an object.. Argh. Object = Object
will just show the entire Object and not the specific shape of my Interface..
HTML: combat-list.component.html
<div *ngFor="let key of Object.keys(lifeTimeStat)"> {{ lifeTimeStats[key].attributes.gameModeStats.solo| json }} </div> <br>
Service Component: combat.service.ts
`@Injectable({
providedIn: 'root'
})
export class CombatService {
getCombat():Observable<lifeTimeStat> {
return this.http.get<lifeTimeStat>(this.configUrl, { observe:'body',
responseType: 'json', headers: getHeaders });
}`
Interface:
`export interface lifeTimeStat {
headshotKills: number,
kills: number,
longestKill: number,
maxKillStreaks: number,
dailyKills: number,
weeklyKills: number,
damageDealt: number,
roadKills: number,
teamKills: number,
vehicleDestroys: number,
suicides: number,
roundMostKills: number,
dBNOs: number,
assists: number,
} `
I just want to show the selected data as I have defined in my Interface. I've been googling / searching on SO for many hours over the course of two, almost three days :(
So this syntax should work:
Object
.keys({ a: 1, b: 2 })
.map(key => console.log(key));
If not, why don't you assign the array to a variable and iterate over the variable?
In any case, you can use this nice helper to preserve types and iterate over both keys and values:
const testObject = {
completed: true,
score: 129.1,
description: 'none',
};
entries(testObject)
.map(([key, value]) => console.log(`Key is ${key}, value is ${value}`));
function entries<K>(object: K) {
return (Object.keys(object) as (keyof K)[])
.filter((key) => object[key] !== undefined && object[key] !== null)
.map(
key => ([
key,
object[key],
] as [keyof K, Required<K>[keyof K]]),
);
}
type Required<T> = {
[P in keyof T]-?: T[P];
};
Or for your case:
const keyValuePairs = entries(lifeTimeStat);
...
<div *ngFor="const [key, value] of keyValuePairs"> {{ value.attributes.gameModeStats.solo| json }} </div> <br>