How to import JSON File into a TypeScript file?
Asked Answered
P

12

140

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!

Passage answered 28/10, 2017 at 15:15 Comment(1)
you can see my answer as it is applicable to Angular 7+Dextrocular
W
214

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.

Womanhood answered 20/2, 2018 at 0:19 Comment(13)
This method worked for me and seems to be the cleanest and most direct way to solving the problem.Potence
This worked for me as well - super slick! NOTE: You need to restart your dev server for this to compile correctly.Candi
@RossRawlins restart your project.Baksheesh
import * as data from './example.json'; and subscribing json which one is preferred and why to subscribe if we can import directly?Orthopedics
Thank you for the link. The article has been updated to work with typescript 2.9+Aesthetic
I'm getting Cannot find module '*.json'. Consider using '--resolveJsonModule' to import module with '.json' extensionts(2732)Littrell
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?Displease
same as comments above I needed "esModuleInterop":true. Also VS code still is showing me an error.. but everything works fineLupita
I had to add "allowSyntheticDefaultImports": true in the compilerOptions as well with a fresh Angular 9.1.11 project.Coppery
restarting VS Code got rid of the error Consider using '--resolveJsonModule'for me.Michal
This change break the import * as moment from 'moment' statement. Changing it to import moment from 'moment' worked. Also, VS Code restart was required.Jenkins
While importing a JSON file works, this should be considered an anti-pattern, since data does not belong together with the code. If your JSON file is more than a couple of kilobytes then you will be better off using HttpClient — apart from separating data and code, this will also allow you to have a progress loader and a fluid UI if your data is big.Concavity
it is returning undefinedCompost
D
70

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.

Dextrocular answered 2/7, 2019 at 15:23 Comment(4)
What is esModuleInterop for?Moina
@Moina it is for default json importsLeffert
In my case, Angular 10 and Typescript 4.0.2, I did not need "allowSyntheticDefaultImports"Witham
Only solution that wokred for me :)Abroms
P
31

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.

Passage answered 6/1, 2018 at 1:58 Comment(3)
I got error TS2304: Cannot find name 'require'. Solved by adding declare var require: any;, as explained in comments of accepted answer for question #43104614.Hbeam
@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: https://mcmap.net/q/63921/-typescript-getting-error-ts2304-cannot-find-name-39-require-39Loathsome
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?Sennight
S
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';

Spaulding answered 26/6, 2018 at 10:19 Comment(3)
What if I don't have a typings.d.ts file?Ciapha
then you have to create one at your project root with only the step 2 contentSpaulding
Important note: Add the custom typing file to typeRoots in tsconfig.json "typeRoots": ["node_modules/@types", "src/typings.d.ts"],Tiffanitiffanie
B
18

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).

Bartko answered 28/10, 2017 at 15:22 Comment(1)
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 hugeBarbra
I
16

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

Interlaken answered 18/12, 2018 at 5:55 Comment(2)
This was the best solution for me. No typings file needed, and TS can resolve the property names for you.Convergent
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!Clerk
T
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';

Telson answered 28/2, 2019 at 23:38 Comment(0)
C
11

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"
  ]
}
Cupel answered 5/12, 2020 at 0:41 Comment(0)
S
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);
    }

}
Sandler answered 12/12, 2018 at 10:59 Comment(3)
data.default was hanging me up. Thanks for the full example!Hoodlum
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.jsonGouache
It work perfectly, but why typings.d.ts file is needed?Constructive
C
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
Coppinger answered 15/11, 2018 at 17:59 Comment(1)
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.Copperhead
H
5

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

const swaggerDoc = require('../swagger.json')
Hautboy answered 21/1, 2021 at 1:44 Comment(0)
O
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);
 }
Orgel answered 28/10, 2017 at 15:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.