145

I am building a map application using Angular Maps and want to import a JSON file as a list of markers defining locations. I'm hoping to use this JSON file as marker[] array inside the app.component.ts . Instead of defining a hardcoded array of markers inside the TypeScript file.

What is the best process of importing this JSON file for use in my project? Any direction greatly appreciated!

1
  • you can see my answer as it is applicable to Angular 7+ Commented Jul 15, 2019 at 14:02

12 Answers 12

217

Aonepathan's one-liner was working for me until a recent typescript update.

I found Jecelyn Yeen's post which suggests posting this snippet into your TS Definition file

add file typings.d.ts to the project's root folder with below content

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

and then import your data like this:

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

update July 2019:

Typescript 2.9 (docs) introduced a better, smarter solution. Steps:

  1. Add resolveJsonModule support with this line in your tsconfig.json file:
"compilerOptions": {
    ...
    "resolveJsonModule": true
  }

the import statement can now assumes a default export:

import data from './example.json';

and intellisense will now check the json file to see whether you can use Array etc. methods. pretty cool.

Sign up to request clarification or add additional context in comments.

13 Comments

This worked for me as well - super slick! NOTE: You need to restart your dev server for this to compile correctly.
I'm getting Cannot find module '*.json'. Consider using '--resolveJsonModule' to import module with '.json' extensionts(2732)
I needed to also add "esModuleInterop": true, as specified in the typescript docs, however they also say to use commonjs as the module instead of esnext. This seems to work with either. Is there any reason to switch to commonjs (as mentioned in the docs) as oppose to stick with the default of esnext?
same as comments above I needed "esModuleInterop":true. Also VS code still is showing me an error.. but everything works fine
I had to add "allowSyntheticDefaultImports": true in the compilerOptions as well with a fresh Angular 9.1.11 project.
|
71

As stated in this reddit post, after Angular 7, you can simplify things to these 2 steps:

  1. Add those three lines to compilerOptions in your tsconfig.json file:
"resolveJsonModule": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
  1. Import your json data:
import myData from '../assets/data/my-data.json';

And that's it. You can now use myDatain your components/services.

4 Comments

What is esModuleInterop for?
@giovannipds it is for default json imports
In my case, Angular 10 and Typescript 4.0.2, I did not need "allowSyntheticDefaultImports"
Only solution that wokred for me :)
32

Thanks for the input guys, I was able to find the fix, I added and defined the json on top of the app.component.ts file:

var json = require('./[yourFileNameHere].json');

This ultimately produced the markers and is a simple line of code.

3 Comments

I got error TS2304: Cannot find name 'require'. Solved by adding declare var require: any;, as explained in comments of accepted answer for question stackoverflow.com/questions/43104114/….
@Ben, you need to add the node type to your tsconfig. i.e. "compilerOptions": { ... "types": ["node"] }, Here is the related answer for those who require it: stackoverflow.com/a/35961176/1754995
Hi @aonepathan, I hope you can help me: I have a library that use require to read a json file. var json = require('./[yourFileNameHere]'); without the extension. At compile time I have an error: Module not found: Error: Can't resolve [yourFileNameHere] in [file name] do you have any idea to bypass this issue?
26

Here is complete answer for Angular 6+ based on @ryanrain answer:

From angular-cli doc, json can be considered as assets and accessed from standard import without use of ajax request.

Let's suppose you add your json files into "your-json-dir" directory:

  1. add "your-json-dir" into angular.json file (:

    "assets": [ "src/assets", "src/your-json-dir" ]

  2. create or edit typings.d.ts file (at your project root) and add the following content:

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

    This will allow import of ".json" modules without typescript error.

  3. in your controller/service/anything else file, simply import the file by using this relative path:

    import * as myJson from 'your-json-dir/your-json-file.json';

3 Comments

What if I don't have a typings.d.ts file?
then you have to create one at your project root with only the step 2 content
Important note: Add the custom typing file to typeRoots in tsconfig.json "typeRoots": ["node_modules/@types", "src/typings.d.ts"],
19

First solution - simply change the extension of your .json file to .ts and add export default at the beginning of the file, like so:

export default {
   property: value;
}

Then you can just simply import the file without the need to add typings, like so:

import data from 'data';

Second solution get the json via HttpClient.

Inject HttpClient into your component, like so:

export class AppComponent  {
  constructor(public http: HttpClient) {}
}

and then use this code:

this.http.get('/your.json').subscribe(data => {
  this.results = data;
});

https://angular.io/guide/http

This solution has one clear adventage over other solutions provided here - it doesn't require you to rebuild entire application if your json will change (it's loaded dynamically from a separate file, so you can modify only that file).

1 Comment

first solution is good if your data is static and will not change for a very long time; it will save you unnecessary http requests, but if this data changes constantly, then use the second solution sent by server or even consider adding it to a database if the data set is huge
18

I had read some of the responses and they didn't seem to work for me. I am using Typescript 2.9.2, Angular 6 and trying to import JSON in a Jasmine Unit Test. This is what did the trick for me.

Add:

"resolveJsonModule": true,

To tsconfig.json

Import like:

import * as nameOfJson from 'path/to/file.json';

Stop ng test, start again.

Reference: https://blogs.msdn.microsoft.com/typescript/2018/05/31/announcing-typescript-2-9/#json-imports

2 Comments

This was the best solution for me. No typings file needed, and TS can resolve the property names for you.
This is a great solution, you don't even have to use JSON.parse(). It's a common TS object right out of the box!
13

As of Typescript 2.9, one can simply add:

"compilerOptions": {
    "resolveJsonModule": true
}

to the tsconfig.json. Thereafter, it's easy to use a json file (and there will be nice type inference in VSCode, too):

data.json:

{
    "cases": [
        {
            "foo": "bar"
        }
    ]
}

In your Typescript file:

import { cases } from './data.json';

Comments

12

Angular 10

You should now edit the tsconfig.app.json (notice the "app" in the name) file instead.

There you'll find the compilerOptions, and you simply add resolveJsonModule: true.

So, for example, the file in a brand new project should look like this:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [],
    "resolveJsonModule": true
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

Comments

8

For Angular 7+,

1) add a file "typings.d.ts" to the project's root folder (e.g., src/typings.d.ts):

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

2) import and access JSON data either:

import * as data from 'path/to/jsonData/example.json';
...
export class ExampleComponent {
    constructor() {
        console.log(data.default);
    }

}

or:

import data from 'path/to/jsonData/example.json';
...
export class ExampleComponent {
    constructor() {
        console.log(data);
    }

}

3 Comments

data.default was hanging me up. Thanks for the full example!
Be careful about the path to your json file because it's relevant to the file you import the file e.g. if you have a service in src/app/services/ folder and your json is in src/assets/data/ folder you have to specify it like ../../assets/data/your.json
It work perfectly, but why typings.d.ts file is needed?
6

In angular7, I simply used

let routesObject = require('./routes.json');

My routes.json file looks like this

{

    "routeEmployeeList":    "employee-list",
    "routeEmployeeDetail":      "employee/:id"
}

You access json items using

routesObject.routeEmployeeList

1 Comment

That's it! ;-) All the other options are so hacky! If you have TSLint will throw a reuqire error - just add declare var require: any; on top of the class component.
6

I couldn't import a different file.json too. But I resolved it like this

const swaggerDoc = require('../swagger.json')

Comments

3
let fs = require('fs');
let markers;
fs.readFile('./markers.json', handleJSONFile);

var handleJSONFile = function (err, data) {
   if (err) {
      throw err;
   }
   markers= JSON.parse(data);
 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.