137

I am using Angular 5 and I've created a service using the angular-cli

What I want to do is to create a service that reads a local json file for Angular 5.

This is what I have ... I'm a bit stuck...

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

@Injectable()
export class AppSettingsService {

  constructor(private http: HttpClientModule) {
    var obj;
    this.getJSON().subscribe(data => obj=data, error => console.log(error));
  }

  public getJSON(): Observable<any> {
    return this.http.get("./assets/mydata.json")
      .map((res:any) => res.json())
      .catch((error:any) => console.log(error));

  }

}

How can I get this finished?

1
  • 1
    angular.io/tutorial/toh-pt6 For example, HttpClientModule should not be injected in constructor. Commented Nov 9, 2017 at 16:30

11 Answers 11

187

First You have to inject HttpClient and Not HttpClientModule, second thing you have to remove .map((res:any) => res.json()) you won't need it any more because the new HttpClient will give you the body of the response by default , finally make sure that you import HttpClientModule in your AppModule :

import { HttpClient } from '@angular/common/http'; 
import { Observable } from 'rxjs';

@Injectable()
export class AppSettingsService {

   constructor(private http: HttpClient) {
        this.getJSON().subscribe(data => {
            console.log(data);
        });
    }

    public getJSON(): Observable<any> {
        return this.http.get("./assets/mydata.json");
    }
}

to add this to your Component:

@Component({
    selector: 'mycmp',
    templateUrl: 'my.component.html',
    styleUrls: ['my.component.css']
})
export class MyComponent implements OnInit {
    constructor(
        private appSettingsService : AppSettingsService 
    ) { }

   ngOnInit(){
       this.appSettingsService.getJSON().subscribe(data => {
            console.log(data);
        });
   }
}
Sign up to request clarification or add additional context in comments.

9 Comments

I'm getting "Unresolved Type Observable" ... on this line "public getJSON(): Observable<any> {"
One last question ... How do I can this data from my component?
i have faced 404 error while fetching json file....and also follow same flow like yours..
I receive 404 with the log GET http://localhost:4200/src/assets/data.json 404 (Not Found)
those who get the 404, is mainly due to that there json file is not in assets folder, incase they you are required to move json file to any other directory then you need to add that in angular.json file
|
36

For Angular 7, I followed these steps to directly import json data:

In tsconfig.app.json:

add "resolveJsonModule": true in "compilerOptions"

In a service or component:

import * as exampleData from '../example.json';

And then

private example = exampleData;

Comments

22

You have an alternative solution, importing directly your json.

To compile, declare this module in your typings.d.ts file

declare module "*.json" {
    const value: any;
    export default value;
}

In your code

import { data_json } from '../../path_of_your.json';

console.log(data_json)

8 Comments

Suppose, I have my json in assets/abc.json, and using only one module app.module.ts then how to declare in typing.d.ts and how to import. Please help.
Just declare the module in your typing.d.ts file. And import your JSON into your class
Which module? Suppose I am using it in app. module. ts?
I got this to work without errors when I did import { default as data_json } from '../../path_of_your.json';
Why am I getting "undefined" in the console?
|
21

I found this question when looking for a way to really read a local file instead of reading a file from the web server, which I'd rather call a "remote file".

Just call require:

const content = require('../../path_of_your.json');

The Angular-CLI source code inspired me: I found out that they include component templates by replacing the templateUrl property by template and the value by a require call to the actual HTML resource.

If you use the AOT compiler you have to add the node type definitons by adjusting tsconfig.app.json:

"compilerOptions": {
  "types": ["node"],
  ...
},
...

2 Comments

To use require I needed to install @types/node by running npm install @types/node --save-dev as discussed here
all these solutions are great, but this is one of the only ones that will allow me to save the values and parse the file content dynamically without an initial import
16

Assumes, you have a data.json file in the src/app folder of your project with the following values:

[
    {
        "id": 1,
        "name": "Licensed Frozen Hat",
        "description": "Incidunt et magni est ut.",
        "price": "170.00",
        "imageUrl": "https://source.unsplash.com/1600x900/?product",
        "quantity": 56840
    },
    ...
]

3 Methods for Reading Local JSON Files

Method 1: Reading Local JSON Files Using TypeScript 2.9+ import Statement

import { Component, OnInit } from '@angular/core';
import * as data from './data.json';

@Component({
  selector: 'app-root',
  template: `<ul>
      <li *ngFor="let product of products">

      </li>
  </ul>`,
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'Angular Example';

  products: any = (data as any).default;

  constructor(){}
  ngOnInit(){
    console.log(data);
  }
}

Method 2: Reading Local JSON Files Using Angular HttpClient

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


@Component({
  selector: 'app-root',
  template: `<ul>
      <li *ngFor="let product of products">

      </li>
  </ul>`,
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'Angular Example';
  products: any = [];

  constructor(private httpClient: HttpClient){}
  ngOnInit(){
    this.httpClient.get("assets/data.json").subscribe(data =>{
      console.log(data);
      this.products = data;
    })
  }
}

Method 3: Reading Local JSON Files in Offline Angular Apps Using ES6+ import Statement

If your Angular application goes offline, reading the JSON file with HttpClient will fail. In this case, we have one more method to import local JSON files using the ES6+ import statement which supports importing JSON files.

But first we need to add a typing file as follows:

declare module "*.json" {
  const value: any;
  export default value;
}

Add this inside a new file json-typings.d.ts file in the src/app folder.

Now, you can import JSON files just like TypeScript 2.9+.

import * as data from "data.json";

2 Comments

In tsconfig.app.json file, need to add "resolveJsonModule": true in "compilerOptions". otherwise there will be error like - Consider using '--resolveJsonModule' to import module with '.json' extension
For method #2, you need to move the file to the public/assets folder, so the file is served as a static file but the server.
7
import data  from './data.json';
export class AppComponent  {
    json:any = data;
}

See this article for more details.

2 Comments

For my local file this was easiest to use. I had to add "allowSyntheticDefaultImports": true to my tsconfig.json 'compilerOptions', but only to stop a linting error for TypeScript, NOT an actual error.
This is the solution: hackeruna.com/2020/04/27/… for this error TS1259
6

Try This

Write code in your service

import {Observable, of} from 'rxjs';

import json file

import Product  from "./database/product.json";

getProduct(): Observable<any> {
   return of(Product).pipe(delay(1000));
}

In component

get_products(){
    this.sharedService.getProduct().subscribe(res=>{
        console.log(res);
    })        
}

1 Comment

Best answer to the moment for the ones that are not able to add "resolveJsonModule": true into their tsconfig
3

Using Typescript 3.6.3, and Angular 6, none of these solutions worked for me.

What did work was to follow the tutorial here which says you need to add a small file called njson-typings.d.ts to your project, containing this:

declare module "*.json" {
  const value: any;
  export default value;
}

Once this was done, I could simply import my hardcoded json data:

import employeeData from '../../assets/employees.json';

and use it in my component:

export class FetchDataComponent implements OnInit {
  public employees: Employee[];

  constructor() {
    //  Load the data from a hardcoded .json file
    this.employees = employeeData;
    . . . .
  }

Comments

1

Let’s create a JSON file, we name it navbar.json you can name it whatever you want!

navbar.json

[
  {
    "href": "#",
    "text": "Home",
    "icon": ""
  },
  {
    "href": "#",
    "text": "Bundles",
    "icon": "",
    "children": [
      {
        "href": "#national",
        "text": "National",
        "icon": "assets/images/national.svg"
      }
    ]
  }
]

Now we’ve created a JSON file with some menu data. We’ll go to app component file and paste the below code.

app.component.ts

import { Component } from '@angular/core';
import menudata from './navbar.json';

@Component({
  selector: 'lm-navbar',
  templateUrl: './navbar.component.html'
})
export class NavbarComponent {
    mainmenu:any = menudata;

}

Now your Angular 7 app is ready to serve the data from the local JSON file.

Go to app.component.html and paste the following code in it.

app.component.html

<ul class="navbar-nav ml-auto">
                  <li class="nav-item" *ngFor="let menu of mainmenu">
                  <a class="nav-link" href="{{menu.href}}">{{menu.icon}} {{menu.text}}</a>
                  <ul class="sub_menu" *ngIf="menu.children && menu.children.length > 0"> 
                            <li *ngFor="let sub_menu of menu.children"><a class="nav-link" href="{{sub_menu.href}}"><img src="{{sub_menu.icon}}" class="nav-img" /> {{sub_menu.text}}</a></li> 
                        </ul>
                  </li>
                  </ul>

Comments

0

For me, it didn't work when I try to import the data file. instead, I have moved the data file to the assets folder and tried to access it through get request.

 public getProjectTree()
   {
      return this.http.get("assets/data.json");
   }

Comments

0

I used JSON file for get API config that changes API URL in realtime

getApiEndpoint() {
    const settings = require('../../../../../assets/apiconfig.json');
    let production = settings['production'] as boolean;
    if (production) {
      return settings['apiEndpoint'];
    } else
      return settings['apiEndpoint-test'];

  }

and then call this method in apiService

Comments