0

I have a JSON database that has some nested Objects in it:

{
"characters2": [
    {
      "campaign":"Menagerie Coast",
      "index": 1,
      "name": "Mark Whithershmitz",
      "portrait": "assets/pics/markW.jpg",
      "affiliation": "Kryn Dynasty",
      "class": "Wizard - Bladesinger",
      "list1": {"Swords":[
        "McClane: Moon-Glow Scimitar",
        "Carver: Shadow Sword"
      ]},
      "list2": {"Remarks about his Race":"5"},
      "title1a":"Sword Count",
      "title1b": "2",
      "title1c": "fa fa-robot",
      "title2a":"Kills",
      "title2b": "0",
      "title2c": "fas fa-skull-crossbones",
      "title3a":"Magic Sword",
      "title3b": "None",
      "title3c": "fas fa-dumpster-fire"
    },
    {
      "campaign":"Menagerie Coast",
      "index": 2,
      "name": "The Hermit II",
      "portrait": "assets/pics/theHermit2.jpg",
      "affiliation": "None?",
      "class": "Rogue/Mastermind",
      "list1": {"Bag of Animal Cotton?": [
        "Lion x 2",
        "Goat"
      ]},
      "list2": [],
      "title1a":"Bar Fights",
      "title1b": "0",
      "title1c": "fas fa-beer",
      "title2a":"Kills",
      "title2b": "0",
      "title2c": "fas fa-skull-crossbones",
      "title3a":"Badassery",
      "title3b": "Medium",
      "title3c": "far fa-laugh-beam"

    }]}

I'm accessing the database by subscribing to an observable:

import { Component, OnInit } from '@angular/core';
import { DndDatabaseService } from 'src/app/dnd-database.service';

@Component({
  selector: 'app-player-card',
  templateUrl: './player-card.component.html',
  styleUrls: ['./player-card.component.scss']
})
export class PlayerCardComponent implements OnInit {
  characters;
  characters2;
  isDataAvailable:boolean = false;


  constructor(private dndDatabaseService: DndDatabaseService) { }

  ngOnInit() {

   this.dndDatabaseService.getCharacters().subscribe(characters => {this.characters = characters as playerData[]})
   this.dndDatabaseService.getCharacters2().subscribe(characters2 => {(this.characters2 = characters2 as playerData[])}) 
   this.isDataAvailable = true;

  }

export class playerData {
  name: string;
  potrait: string;
  affiliation:string;
  class: string;
  list1: object;
  list2: object;
  campaign: string;
  index: number;
  title1a:string;
  title1b: string;
  title2a:string;
  title2b: string;
  title3a:string;
  title3b: string;
}

The databsse service is a simple http.get call which returns the json.

I'm creating HTML objects using *ngFor which works for everything except the list1 and list2 objects.

<div *ngFor character in characters2 >
        <h1>{{character.name}}</h1> 

        <p>{{(character.list1}}</p>
        <p>({{character.list2}})</p>
</div>

The output for list1 and 2 with this code is just [object Object]. I can't use the key that's inside the object (character.list1.Swords for example) because I want to be able to have different objects under list1 and list2 for different characters.

What is the best way to get this info to display? I could write a new observable but I'm sure that isn't the "best" way. I have tried using the json pipe but that displays the JSON with the braces. I could probably css that away but that doesn't seem to be the best solution either.

I'm sure there's something I can do either in the subscription to the observable or in the HTML, but I haven't been able to find anything.

3
  • you have a syntax error in your first <p> tag: <p>{{(character.list1}}</p> should be <p>{{ (character.list1) }}</p> If that doesn't fix it then try: <p>{{JSON.stringify(character.list1)}}</p>`? Commented Apr 17, 2020 at 15:35
  • Actually, I was wrong about the revision. It should be <p>{{character.list1}}</p>, without the (. Commented Apr 17, 2020 at 16:33
  • That's a good catch! the extra parentheses is from prior attempts to get this to output like I wanted it too. Commented Apr 18, 2020 at 11:12

1 Answer 1

1

Please try like this . In the template you can keyvalue pipe . using this pipe you can access the key and value of the objects item1 and item2.

characters2 = {
    characters2: [
      {
        campaign: "Menagerie Coast",
        index: 1,
        name: "Mark Whithershmitz",
        portrait: "assets/pics/markW.jpg",
        affiliation: "Kryn Dynasty",
        class: "Wizard - Bladesinger",
        list1: {
          Swords: ["McClane: Moon-Glow Scimitar", "Carver: Shadow Sword"]
        },
        list2: { "Remarks about his Race": "5" },
        title1a: "Sword Count",
        title1b: "2",
        title1c: "fa fa-robot",
        title2a: "Kills",
        title2b: "0",
        title2c: "fas fa-skull-crossbones",
        title3a: "Magic Sword",
        title3b: "None",
        title3c: "fas fa-dumpster-fire"
      },
      {
        campaign: "Menagerie Coast",
        index: 2,
        name: "The Hermit II",
        portrait: "assets/pics/theHermit2.jpg",
        affiliation: "None?",
        class: "Rogue/Mastermind",
        list1: { "Bag of Animal Cotton?": ["Lion x 2", "Goat"] },
        list2: [],
        title1a: "Bar Fights",
        title1b: "0",
        title1c: "fas fa-beer",
        title2a: "Kills",
        title2b: "0",
        title2c: "fas fa-skull-crossbones",
        title3a: "Badassery",
        title3b: "Medium",
        title3c: "far fa-laugh-beam"
      }
    ]
  };

<div *ngFor="let character of characters2.characters2">
    <h1>{{character.name}}</h1>
    <div *ngFor="let item of character.list1 |keyvalue">
        <span>{{item.key}}</span> : <span>{{item.value}}</span>
    </div>

    <div *ngFor="let item of character.list2 |keyvalue">
            <span>{{item.key}}</span> : <span>{{item.value}}</span>
    </div>
</div>
Sign up to request clarification or add additional context in comments.

1 Comment

This worked! I didn't think to do sub-*ngFor statements like that. Thanks a ton!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.