9

I have an array of objects in a json file. I'm trying to import this file into another file so I can reference the data in a simple react project.

I've tried various combinations of export default and named exports but the JSON file is always complaining when I save it. Here is what I am trying to achieve:

(File1.json)

    [
      {
        "userId": 1,
        "id": 1,
        "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
        "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
      }
    ]

File2.js

import data from '.\file1.json'

console.log(data.id);

The issue I'm having is that I see no errors in my JS file but the data.id value isn't being displayed. However in my JSON file, I am having problems exporting it to use.

Question: How to import ".json" file (not ".js") with objects file using es6?

Update I've managed to make it work in the create-react-app environment, I left the json file as an array of objects, then in the js file I used "import xyx from './xyz';"

This worked for me, this answer isn't mentioned in the duplicate marked post so I think it should have it's own answer - hopefully this helps someone else.

j obe
  • 1,759
  • 4
  • 15
  • 23
  • 1
    Complaining about what exactly? – Teemu Feb 04 '19 at 17:45
  • 1
    Export is an ES6 Feature and not a feature of JSON, JSON is a different standard to ES6, [rfc7159](https://tools.ietf.org/html/rfc7159) – Barkermn01 Feb 04 '19 at 17:45
  • 1
    Please provide a Minimal, Verifiable, Complete example. See this: https://stackoverflow.com/help/mcve – McHat Feb 04 '19 at 17:46
  • I have updated the code to just demonstrate what I am trying to do, basically I'd like to make the data from this file be available to be imported into another file in a variable e.g. "import sample from 'sample.json' – j obe Feb 04 '19 at 17:54
  • @Teemu It complains on the export keyword - saying it expects an array or object literal – j obe Feb 04 '19 at 17:55
  • @MartinBarker that's correct, I'm trying to use it as a default export from one file to use as an import in a JS file. – j obe Feb 04 '19 at 17:56
  • Apologies, the actual code is on another machine, so I'm not able to paste the exact file in at the moment. – j obe Feb 04 '19 at 17:57
  • I have never tried this before, I'm able to make imports and exports work with functions or variables etc in JS files but I've never done it with a JSON file in this way, it's a learning exercise for me as a noob. – j obe Feb 04 '19 at 17:58
  • @jobe `Unexpected token e in JSON at position 0` are you getting this error ? – Code Maniac Feb 04 '19 at 17:59
  • @Ry to be fair the question title mentions exports and imports with es6 but I'm just looking for an answer now :) – j obe Feb 04 '19 at 18:21
  • @jobe: Right, but the important part is the file extension. (Although I’m still not sure how you could get both a JSON parsing error when using `export default` and no data without it. Are there multiple environments involved? Are you using a transpiler?) – Ry- Feb 04 '19 at 18:22
  • @Ry- Ok, if you're able to take it off hold and maybe if you can help with the answer that would help me a lot, thanks again. – j obe Feb 04 '19 at 18:23
  • 1
    @jobe: Or did you determine “no data” from `console.log(data.id)` producing `undefined`? It should be `data[0].id`, since the export is an array. – Ry- Feb 04 '19 at 18:23
  • @Ry- sorry my bad as I don't have the actual code to hand but I am using a forEach method on the array. – j obe Feb 04 '19 at 18:24
  • I'm a noob so not even sure people use JSON files this way or if it's a common thing to do, I couldn't find many examples online. – j obe Feb 04 '19 at 18:25
  • Well, I hope these questions give you an idea of why the actual code is important =) Will you be able to edit in the actual code sometime later? In the meantime, knowing the environment would also help, e.g. native modules in browser, native modules in Node.js experimental, ESM bundler, magic ESM shim, … – Ry- Feb 04 '19 at 18:28
  • @Ry- I'm using create-react-app and in the basic app, I have the app.js file which is importing this JSON file. I'd like to display values from this JSON data. – j obe Feb 04 '19 at 18:30
  • @jobe Can I know why you don't want to load your json file dynamically using ajax? – Kamil Kiełczewski Feb 04 '19 at 18:31
  • @KamilKiełczewski this is a learning exercise I'm trying to do, I haven't started using ajax or other ways yet. – j obe Feb 04 '19 at 18:33
  • @jobe so in my opinion your question is pure abstract/theoretical and probably will be never used in practice because usually we import .js files with code (not .json files with data) - and probably this is bad practice (counter-desing) – Kamil Kiełczewski Feb 04 '19 at 18:34
  • @KamilKiełczewski I have a practical exercise which requires me to do it, if it's possible to be done, I should be able to do it. I'm sure there are cases when you may have a static file to import data from. – j obe Feb 04 '19 at 18:36
  • @jobe yes but if you have static file with data then you just use ".js" file (not ".json" file) – Kamil Kiełczewski Feb 04 '19 at 18:38
  • @KamilKiełczewski Yes I agree and I know that way will work but I've been asked to do it with a JSON file. – j obe Feb 04 '19 at 18:39
  • @jobe don't get me wrong - I don't say that theoretical questions are bad – Kamil Kiełczewski Feb 04 '19 at 18:40
  • @jobe your json file is invalid - `export default sample = ` are not allowed in json file - I edit your question and fix this problem – Kamil Kiełczewski Feb 04 '19 at 18:56
  • @KamilKiełczewski Yes I know it's invalid, I was merely trying to show what I'm trying which isn't working. – j obe Feb 04 '19 at 19:31
  • @KamilKiełczewski I have tried the solutions in the duplicate post and none of them worked for me. – j obe Feb 04 '19 at 19:52
  • "*I think it should have it's own answer*" - yes, please post a new answer over there! – Bergi Feb 04 '19 at 20:40
  • @Bergi It already has an accepted answer over there. – j obe Feb 04 '19 at 20:54
  • @jobe Doesn't mean that you can't add another one. It might not get accepted by the OP, but will certainly be upvoted by everyone who's working in a create-react-app environment as well. – Bergi Feb 04 '19 at 21:15
  • @jobe Are there any restrictions on how the URL string is constructed within ` – guest271314 Feb 04 '19 at 23:52
  • @guest271314 in question title OP says that import must be done using es6 - so `fetch()` as far I know is not allowed because is not part of es6 – Kamil Kiełczewski Feb 05 '19 at 03:24
  • @jobe solution in your update is similar to [this](https://stackoverflow.com/a/34946395/860099) but its uses webpack so it cannot apply to your question (es6 only allowed). So update your question – Kamil Kiełczewski Feb 05 '19 at 03:31
  • @KamilKiełczewski Technically `import` and `export` is part of the WHATWG HTML Standard https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-module-system some of the same authors of the Fetch Standard https://fetch.spec.whatwg.org/. What exactly do you mean by _"es6"_? What specification are you referring to which defines the mechanism of `import` and `export` that is not the HTML Standard? – guest271314 Feb 05 '19 at 06:39
  • @guest271314 I think es6 is described [here](http://www.ecma-international.org/ecma-262/6.0/) I cannot find there information about `fetch` but I can find there info about `import` – Kamil Kiełczewski Feb 05 '19 at 06:48
  • @KamilKiełczewski That does not negate the fact that `import` and `export` are defined in the HTML Standard and maintained by the WHATWG. The `javascript` tag is at the question, which includes `Fetch`. The text of the question does not explicitly restrict how the URL passed to `import` can be constructed, thus the question to the OP. – guest271314 Feb 05 '19 at 06:50

2 Answers2

6

Since you're storing as JSON extension you should not use export const data = ...

You should directly store the data

xyz.json

[
      {
        "userId": 1,
        "id": 1,
        "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
        "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
      }
    ]

JSON

For demo you can see this

Or you can set extension to .js

const export data = ...some data

at required place

import {data} from '../filepath'
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • 1
    How is then imported to be used in another file? I tried this method also but none of the data then appears in the other file? How would the import statement look if both files are in the same folder? – j obe Feb 04 '19 at 18:08
  • 1
    @jobe you can see here https://repl.it/@VivekJain1/ImportantFriendlyWebmaster – Code Maniac Feb 04 '19 at 18:45
  • Is it possible to do this in es6 using modules and import statements? I thought they can be used instead of require statements. This is the exact problem though. – j obe Feb 04 '19 at 18:56
  • @jobe yes it can be all we need is to setup transpiler. i am not familiar with `REPL` but wait let me try to do it – Code Maniac Feb 04 '19 at 18:58
  • ok - I am reading some other posts too. – j obe Feb 04 '19 at 19:18
  • Any luck Code Maniac? – j obe Feb 04 '19 at 19:52
-1

One workaround for the default HTML standard prohibition of importing files not served as */javascript is to use fetch() to get the file, then export the result as default and import a data URL

<script type="module">
  (async() => {
    let {default:sample} = await import(`data:application/javascript,${encodeURIComponent('export default ')}${JSON.stringify(await(await fetch('file.json')).json())}`);
    console.log(sample);
  })()
</script>

plnkr

See also ES6 modules in local files - The server responded with a non-JavaScript MIME type

guest271314
  • 1
  • 15
  • 104
  • 177
  • @guest271314 I will try that but a developer friend of mine mentioned not having to change the file extension to make it work - it does work the way you're suggesting but I'm trying to see if the JSON extension method will work. – j obe Feb 04 '19 at 18:32
  • @jobe `Failed to load module script: The server responded with a non-JavaScript MIME type of "application/json". Strict MIME type checking is enforced for module scripts per HTML spec.` Did your "developer friend" share working code with you to prove their claim? – guest271314 Feb 04 '19 at 18:34
  • @guest271314 No he didn't it was meant to be my learning exercise to make it work. He did show me a working version with a JSON file but not in detail. – j obe Feb 04 '19 at 18:37
  • @KamilKiełczewski How do you propose to include `export` in a valid `JSON` file? – guest271314 Feb 04 '19 at 18:54
  • @guest271314 Thanks for your answer, I'm trying to find a way to do it with a JSON file extension. – j obe Feb 04 '19 at 19:32
  • @jobe Why does the extension need to be `.json`? As pointed out above, you can use `` or `fetch()`. Or use non-standard third-party code (as suggested in the linked question). Valid `JSON` cannot contain an `export` statement preceding valid `JSON`, which would result in invalid `JSON`. Refer to the HTML Standard https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-module-system – guest271314 Feb 04 '19 at 19:39
  • @jobe See also [Is there a way to know if a link/script is still pending or has it failed](https://stackoverflow.com/q/39824927/) – guest271314 Feb 04 '19 at 19:48
  • @jobe The requirement is currently not possible using JavaScript shipped with the browser for the reasons stated above. First there is the issue of an `export` statement in valid `JSON` which would render the `JSON` invalid. Have you read the linked specification? – guest271314 Feb 04 '19 at 19:53
  • It might have got missed but I mentioned in another comment I am doing this in create-react-app which has webpack etc all bundled up. Some posts I have read suggest this is possible. – j obe Feb 04 '19 at 19:55
  • @jobe According to answers at the linked question the requirement apparently is possible using non-standard, third-party code which transforms or modifies the request/response - not standard, non-third-party default methods shipped with the browser. Have not tried webpack or react. The answer is based on standard HTML and JavaScript shipped with the browser - without using any third-party, non-standard code or libraries. – guest271314 Feb 04 '19 at 19:57
  • @jobe Note HTML Imports are deprecated for Chromium/Chrome 73 https://www.chromestatus.com/features/5144752345317376 – guest271314 Feb 04 '19 at 20:12