0

This was answered below:

I've been having trouble rendering the API results from a simple fake JSON. The JSON is at this endpoint: https://testapi.io/api/crimsonsunset/code-challenge-jobs

My service.ts looks like this:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor(private http: HttpClient) { }

  getJobs() {
    return this.http.get('https://testapi.io/api/crimsonsunset/code-challenge-jobs')
  }
}

My home.component.ts looks like this:

import { Component, OnInit } from '@angular/core';
import { ApiService } from '../services/api.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

  jobs: Object;

  constructor(private data: ApiService) { }

  ngOnInit() {
    this.data.getJobs().subscribe(data => {
      this.jobs = data
      console.log(this.jobs)
    })
  }

}

My home.component.html looks like this:

<div class="bg">

<h1 class="header">Welcome to your next big role</h1>

<app-search></app-search>

<div style="padding: 20px;">

    <mat-card *ngFor="let job of jobs.data" style="margin-top:10px;">
            <mat-card-header>
            <mat-card-title >The role: {{job.title}}</mat-card-title>
            <mat-card-subtitle>{{job.city}} , {{job.state}}
            </mat-card-subtitle>
        </mat-card-header>

        <mat-card-content>
        <mat-accordion>
            <mat-expansion-panel (opened)="panelOpenState = true" (closed)="panelOpenState = false">
            <mat-expansion-panel-header>
                <mat-panel-description>
                    Full Description:
                </mat-panel-description>
            </mat-expansion-panel-header>
                <p>Info from JSON</p>
            </mat-expansion-panel>
        </mat-accordion>
        </mat-card-content>
    </mat-card>
</div>
</div>

I feel as though I'm just making a simple syntax error to render the data. It's console.logging everything correctly. It seems as though it's not seeing where data is in jobs.data on the HTML file.

  • What exactly do you mean by *"seems as though..."*? This is likely a duplicate of e.g. https://stackoverflow.com/questions/39755336/angular2-cannot-read-property-name-of-undefined – jonrsharpe Nov 17 '19 at 17:19
  • What does `console.log(this.jobs)` write on the console? – Nicholas K Nov 17 '19 at 17:59
  • Hi @NicholasK, I get the full JSON back. {jobs: Array(10), totalCount: 30, count: 30, filter: {…}, languageCounts: {…}, …} count: 30 filter: {displayLimit: 10, categories: {…}, brands: {…}, experienceLevels: {…}, locations: {…}, …} jobs: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}] languageCounts: {en-us: {…}} locations: [] meta_data: {ResponseMetadata: {…}} request_id: false totalCount: 30 __proto__: Object – bleauwonder Nov 17 '19 at 19:00
  • Generally, when describing a problem, you need to be clear on what it is doing that is different from what you expect. I don’t see what the issue is in this question. – theMayer Nov 17 '19 at 19:51
  • It was answered quite clearly for me @theMayer. thank you – bleauwonder Nov 17 '19 at 20:23

1 Answers1

0

For a clear understanding, you can edit your service call in this way,

this.data.getJobs().subscribe(response => {
  this.jobs = response['jobs'];
  console.log(response);
})

Now in your HTML,

<mat-card *ngFor="let job of jobs" style="margin-top:10px;">
    <mat-card-header>
        <mat-card-title >The role: {{job['data'].title}}</mat-card-title>
        <mat-card-subtitle>{{job['data'].city}} , {{job['data'].state}}
        </mat-card-subtitle>
    </mat-card-header>

RECOMMENDED METHOD

Even the above code fixes your problem, it is not the recommended way of processing the data. The api indeed looks complex. In this case, you may have to modify your data in a straightforward manner.

this.data.getJobs().subscribe(response => {
    let job: any = {};
    response['jobs'].forEach(element => {
        let keys:any = Object.keys(element.data);
        keys.forEach(function(key) {
            job[key] = element.data[key];
        });
        this.jobs.push(job);
    });
});

In HTML,

<mat-card *ngFor="let job of jobs.data" style="margin-top:10px;">
    <mat-card-header>
        <mat-card-title >The role: {{job.title}}</mat-card-title>
        <mat-card-subtitle>{{job.city}} , {{job.state}}
        </mat-card-subtitle>
    </mat-card-header>
</mat-card>
Angela Amarapala
  • 1,002
  • 10
  • 26