angulartypescriptjsonplaceholder

How to fetch records from Json Placeholder, store it in an array and print on screen


I'm using Json placeholder. I want to learn how to fetch records from remote server and use it. Here is my code:

import { Component, OnInit } from '@angular/core';

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

  myStringifiedJson;

  constructor() {
    console.log(this.myStringifiedJson["title"]);
  }

  ngOnInit() {
    fetch('https://jsonplaceholder.typicode.com/photos')
    .then(response => response.json())
    .then(json => this.myStringifiedJson=JSON.parse(json));
  }
}

I'm getting this error:

ERROR TypeError: this.myStringifiedJson is undefined

Here is the stackblitz. Please correct me. Do I have to use stringify here ?


Solution

  • I see multiple issues here

    1. The variable myStringifiedJson is assigned asynchronously. So by the time you're console logging, it isn't assigned any value yet. Hence the undefined error in the console. You could find more info about async data here.

    2. The value returned from the response.json() is already a valid JS object. The JSON.parse() isn't required.

    3. The object returned from https://jsonplaceholder.typicode.com/photos is actually an array. So you can't access the property title directly. You could however use Array#map method to get all the titles as an array.

    Try the following

    export class PhotographsComponent implements OnInit {
      myStringifiedJson: any;
    
      constructor() { }
    
      ngOnInit() {
        fetch('https://jsonplaceholder.typicode.com/photos')
          .then(response => response.json())
          .then(json => {
            this.myStringifiedJson = json;
            console.log(this.myStringifiedJson.map(t => t['title']));    // <-- print here
          });
      }
    }
    

    I've updated your Stackblitz


    That said I'd recommend you to use Angular's HttpClient to make HTTP requests instead of fetch. It works in tandem with RxJS observables and provides many advantages like combining the response with RxJS operators and functions.

    app.module.ts

    import { HttpClientModule } from '@angular/common/http';
    
    @NgModule({
      imports:      [ BrowserModule, FormsModule, HttpClientModule ],
      ...
    })
    export class AppModule { }
    

    photographs.component.ts

    export class PhotographsComponent implements OnInit {
      myStringifiedJson: any;
    
      constructor(private http: HttpClient) { }
    
      ngOnInit() {
        this.http.get('https://jsonplaceholder.typicode.com/photos').subscribe(
          response => {
            this.myStringifiedJson = response;
            console.log(this.myStringifiedJson.map(t => t['title']));
          },
          error => { console.log(error); }
        );
      }
    }
    

    Working example: Stackblitz

    Update: use *ngFor

    You need to bind a variable before you could use the index local variable. Also each element of the array is an object, so without the json pipe it'd just render [object Object].

    <p *ngFor="let item of myStringifiedJson">
      {{ item | json }}
    </p>
    

    Working example: Stackblitz