13

In my Angular project I'm importing JSON files for my own little localization service. I'm using the method suggested here, updating my typings.d.ts to

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

This worked fine for Angular 6, but after the update to Angular 7 my imports seem to be undefined when I try to access a property.

import * as de from './strings/de.json';
import * as en from './strings/en.json';

var s = en["mykey"]

The JSON has a very simple key => value structure:

{
  "myKey": "My Headline",
  …
}

What has changed between 6.1 & 7 that could lead to this behaviour?

7
  • Can you share the en.json content format ? Commented Oct 19, 2018 at 8:18
  • I've added it to the question Commented Oct 19, 2018 at 8:19
  • en["mykey"] is undefined but what about en, what's its value ? Commented Oct 19, 2018 at 8:24
  • Interestingly on closer inspection it seems that all values have been wrapped inside a new 'default'-object. Any ideas where this could be comming from? Commented Oct 19, 2018 at 8:31
  • 1
    Did you check the typescript version coming with Angular 7? Maybe there is something. Commented Oct 19, 2018 at 8:39

4 Answers 4

20

Turns out with Angular 7 & TypeScript 3.1 there actually have been some changes (I guess they have been there since TS 2.9+?). Using the code in the question, all values are wrapped inside a 'default'-object. To prevent this I had to simplify the import statements:

import de from './strings/de.json';
import en from './strings/en.json';

Also see this question for more details on how to import JSON files in TypeScript.

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

1 Comment

This was the explanation and solution I was looking for ^^^. Thanks!
13

After a lot of digging and trail and error, I finally got my app to import JSON correctly in Angular 7:

  1. Firstly, remove

    "resolveJsonModule": true
    "esModuleInterop": true
    

    from tsconfig.json, if you have that in there from other non-Angular 7 specific answers.

  2. Create src/typings.d.ts:

    declare module "*.json" {
      const value: any;
      export default value;
    }
    
  3. Update typeRoots in tsconfig.json to use src/typings.d.ts, e.g:

    "typeRoots": [
      "node_modules/@types",
      "src/typings.d.ts"
    ],
    
  4. Import JSON:

    import data from './data.json';
    console.log(data);
    

1 Comment

It should be noted that this is not necessary for importing into a component. It only seems necessary for importing into a service (or like entity?).
7

In Angular 7 I had to take these steps:

(1) imports

import pkg from '../../package.json'

(2) tsconfig.json

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    AND more compiler options here
  }
}

(3) angular.json (to stop ng lint breaking on JSON imports)

The only change here is to add ... "**/*.json"

"lint": {
  "builder": "@angular-devkit/build-angular:tslint",
  "options": {
    "tsConfig": [
      "src/tsconfig.app.json",
      "src/tsconfig.spec.json"
    ],
    "exclude": [
      "**/node_modules/**",
      "**/*.json"
    ]
  }
}

1 Comment

using import * from * without setting "allowSyntheticDefaultImports" to true in the tsconfig.json file would lead to errors, the above instruction as to go about is, however, valid, take note
0

I was looking for a solution that would work without me tinkering with the angular.json file

I solved it by exporting my JSON as a .ts constant:

export const TEST_DATA = {...};

and then import it to my components

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.