I am trying to fetch data from a JSON file and display that data in the form

JSON FILE Link: https://raw.githubusercontent.com/datameet/railways/master/trains.json

I am trying with the below code. But it returns following error in fetchdata.component.ts file:

Property 'json' does not exist on type 'Object'.

fetchdata.component.ts

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

@Component({
  selector: 'app-fetchdata',
  templateUrl: './fetchdata.component.html',
  styleUrls: ['./fetchdata.component.css']
})

export class FetchdataComponent implements OnInit {

  private _trainUrl = "https://raw.githubusercontent.com/datameet/railways/master/trains.json
";
  items : any;
  constructor(private http:HttpClient) {
    this.http.get( this._trainUrl)
      .subscribe(res => this.items = res.json());
    console.log(this.items);
  }

  ngOnInit() {
  }

}

fetchdata.component.html

<select>
  <option  *ngFor="let item of items" [value]="item.properties.from_station_name">{{item.properties.from_station_name}}</option>
</select>

Please help.

5 Answers

3
Community On Best Solutions

The response probably isn't what you think. I suggest you console.log() the response of your query to see what it actually looks like:

    items : any;
    constructor(private http:HttpClient) {
      this.http.get( this._trainUrl)
        .subscribe(res => {
          this.items = res.features; 
          console.log("Response", res);
          console.log(res.features)
        });
    }

You'll see that you actually get something like this in your console:

{type: "FeatureCollection", features: Array(5208)}
features: (5208) [{…}, …]
type: "FeatureCollection"
__proto__: Object

So you can assign your items to the features key as that's what you really need:

 constructor(private http:HttpClient) {
      this.http.get( this._trainUrl)
        .subscribe(res => {
          this.items = res["features"]; 
        });
    }

Then your select options should show up.

Just letting you know, this isn't the perfect way to do it but it works fine for a small example like this. I suggest you look into creating a service for any request in the future (doing it in the constructor isn't the best way) and have a look at the RxJS library

0
Vitalii Chmovzh On

You don't need to call .json() function in case you doing plain this.http.get. Angular does that for you. Simply do this.items = res. That will do the trick.

UPD: your JSON object is not an array itself. You as well need to update your template in the following way:

<select>
  <option  *ngFor="let item of items.features" [value]="item.properties.from_station_name">{{item.properties.from_station_name}}</option>
</select>
1
ashish.gd On

There is a difference between Angular's Http and HttpClient module and they are also exported differently.

  1. Http -> is the core module which requires the user to call res.json(). This was common prior to Angular version 4.0.

  2. HttpClient -> is new module since version 4.0. It defaults the communication to json and hence you don't need to call res.json() explicitly.

In short, changing from res.json() to just res will fix the issue for you.

i.e this.items = res; should be fine.

Also, as a good practice use the ngOnInit lifecycle method instead of the constructor to make any Http calls.

0
Daniel Schmid On

Why do you do this.items = res.json()? Why not just this.items = res? res should already hold the JSON object returned from the GET request. If it is indeed a string try this.items = JSON.parse(res).

0
CHIRAG DOSHI On

Can you try :

private _trainUrl = "https://raw.githubusercontent.com/datameet/railways/master/trains.json";
  items : any;
constructor(private http:HttpClient) {}


  ngOnInit() {
    this.http.get( this._trainUrl).subscribe(res => {
      this.items = res;
      console.log(this.items);
    });
  }