Charger le fichier JSON local dans la variable

113

J'essaye de charger un fichier .json dans une variable en javascript, mais je n'arrive pas à le faire fonctionner. C'est probablement juste une erreur mineure mais je ne la trouve pas.

Tout fonctionne très bien lorsque j'utilise des données statiques comme celle-ci:

var json = {
  id: "whatever",
  name: "start",
  children: [{
      "id": "0.9685",
      "name": " contents:queue"
    }, {
      "id": "0.79281",
      "name": " contents:mqq_error"
    }
  }]
}

J'ai mis tout ce qui se trouve dans {}un content.jsonfichier et j'ai essayé de le charger dans une variable JavaScript locale comme expliqué ici: chargez json dans une variable .

var json = (function() {
  var json = null;
  $.ajax({
    'async': false,
    'global': false,
    'url': "/content.json",
    'dataType': "json",
    'success': function(data) {
      json = data;
    }
  });
  return json;
})();

Je l'ai exécuté avec le débogueur Chrome et il me dit toujours que la valeur de la variable jsonest null. Le content.jsonfichier réside dans le même répertoire que le fichier .js qui l'appelle.

Qu'est-ce que j'ai raté?

PogoMips
la source
1
L'URL de votre fichier est /content.jsonce qui signifie que le fichier se trouve au niveau racine de votre application Web. Passez à content.json(sans barre oblique) pour le pointer dans le même répertoire où votre fichier de script est placé. Seulement dans le cas où votre fichier de script est dans le répertoire de niveau racine, cela fonctionnera.
Samich
le fichier réside dans WebContent \ jit \ content.json .. J'ai essayé 'url': "/WebContent/jit/content.json", mais la variable est toujours nulle
PogoMips

Réponses:

38

Si vous avez collé votre objet content.jsondirectement dans , il s'agit d'un JSON non valide. Les clés et les valeurs JSON doivent être placées entre guillemets ( "pas ') sauf si la valeur est numérique, booléenne nullou composite (tableau ou objet). JSON ne peut pas contenir de fonctions ou de undefinedvaleurs. Voici votre objet en tant que JSON valide.

{
  "id": "whatever",
  "name": "start",
  "children": [
    {
      "id": "0.9685",
      "name": " contents:queue"
    },
    {
      "id": "0.79281",
      "name": " contents:mqq_error"
    }
  ]
}

Vous aviez également un extra }.

Kevin B
la source
1
Je ne peux pas croire que cela a résolu le problème .. pourquoi cela fonctionnerait-il directement intégré dans le fichier .js sans guillemets, mais pas dans le fichier .json? Cela n'a aucun sens ...
PogoMips
16
@ user1695165 - json et un objet javascript sont deux choses différentes, ils se ressemblent simplement.
adeneo le
2
@Kevin B "... sauf si la valeur est numérique [ou booléenne]."
Jacob Beauchamp
1
Juste un conseil: vous pouvez utiliser un validateur json comme jsonlint.com afin de vérifier vos données json avant de l'utiliser.
Marco Panichi
129

Ma solution, comme répondu ici , est d'utiliser:

    var json = require('./data.json'); //with path

Le fichier est chargé une seule fois, les autres requêtes utilisent le cache.

edit Pour éviter la mise en cache, voici la fonction d'assistance de cet article de blog donnée dans les commentaires, en utilisant le fsmodule:

var readJson = (path, cb) => {
  fs.readFile(require.resolve(path), (err, data) => {
    if (err)
      cb(err)
    else
      cb(null, JSON.parse(data))
  })
}
Ehvince
la source
48
Je voulais juste préciser que cette solution nécessite une bibliothèque supplémentaire nommée RequireJS .
Luis Kabongo
4
Comment éviter la mise en cache?
nono
2
Non recommandé selon Guilherme Oenning goenning.net/2016/04/14/stop-reading-json-files-with-require
Sangimed
2
TLDR; la mise en cache l'a frappé dans les tests unitaires et il lui donne donc une fonction d'aide pour éviter la mise en cache (ping @nono).
Ehvince
@Ehvince Oh, je n'ai pas remarqué cela puisque je n'ai pas lu l'article en entier. Merci :-)
Sangimed
50

Pour ES6 / ES2015, vous pouvez importer directement comme:

// example.json
{
    "name": "testing"
}


// ES6/ES2015
// app.js
import * as data from './example.json';
const {name} = data;
console.log(name); // output 'testing'

Si vous utilisez Typescript, vous pouvez déclarer un module json comme:

// tying.d.ts
declare module "*.json" {
    const value: any;
    export default value;
}

Depuis Typescript 2.9+, vous pouvez ajouter - resolverJsonModule compilerOptions danstsconfig.json

{
  "compilerOptions": {
    "target": "es5",
     ...
    "resolveJsonModule": true,
     ...
  },
  ...
}
Petits Roys
la source
5
l'importation ne fonctionne pas dans Chrome v72 - toujoursUncaught SyntaxError: Unexpected token *
1000Gbps
2
Quand j'utilise cela, il semble que ce datasoit un module mais data.defaultc'est l'objet
Dustin Michels
1
J'essayais de l'exécuter dans la console, mais sans succès. Cela ne fonctionne pas avec le nœud v12.4.0, avec babel-node 6.26.0. Je reçois toujoursSyntaxError: Unexpected token *
mario199
2
pour ES6 / ES2015, vous pouvez importer directement: il semble que j'obtienne une erreur de console en import * as data from './example.json'raison d'une erreur de type mime.
Fallenreaper
si j'utilise import * as data from './example.json';alors datac'est juste un module, mais data.defaultc'est l'objet. Mais quand j'utilise import data from './example.json';alors datac'est l'objet, qui est plus applicable
Nel
4

Il y a deux problèmes possibles:

  1. AJAX est asynchrone, il jsonne sera donc pas défini lorsque vous reviendrez de la fonction externe. Lorsque le fichier a été chargé, la fonction de rappel sera définie jsonsur une certaine valeur mais à ce moment-là, personne ne s'en soucie plus.

    Je vois que vous avez essayé de résoudre ce problème avec 'async': false. Pour vérifier si cela fonctionne, ajoutez cette ligne au code et vérifiez la console de votre navigateur:

    console.log(['json', json]);
  2. Le chemin pourrait être erroné. Utilisez le même chemin que celui utilisé pour charger votre script dans le document HTML. Donc, si votre script est js/script.js, utilisezjs/content.json

    Certains navigateurs peuvent vous montrer à quelles URL ils ont tenté d'accéder et comment cela s'est passé (codes de réussite / d'erreur, en-têtes HTML, etc.). Consultez les outils de développement de votre navigateur pour voir ce qui se passe.

Aaron Digulla
la source
Peut-être que sa version de jquery ne prend pas encore en charge cela? J'ai amélioré le libellé.
Aaron Digulla
4

Le module node.js intégré fs le fera de manière asynchrone ou synchrone en fonction de vos besoins.

Vous pouvez le charger en utilisant var fs = require('fs');

Asynchrone

fs.readFile('./content.json', (err, data) => {
    if (err)
      console.log(err);
    else {
      var json = JSON.parse(data);
    //your code using json object
    }
})

Synchrone

var json = JSON.parse(fs.readFileSync('./content.json').toString());
Arnaud M.
la source
-1

Pour le format json donné comme dans le fichier ~ / my-app / src / db / abc.json:

  [
      {
        "name":"Ankit",
        "id":1
      },
      {
        "name":"Aditi",
        "id":2
      },
      {
        "name":"Avani",
        "id":3
      }
  ]

afin d'importer dans un fichier .js comme ~ / my-app / src / app.js:

 const json = require("./db/abc.json");

 class Arena extends React.Component{
   render(){
     return(
       json.map((user)=>
        {
          return(
            <div>{user.name}</div>
          )
        }
       )
      }
    );
   }
 }

 export default Arena;

Production:

Ankit Aditi Avani
Ank_247shbm
la source
Ceci est une réponse à une question qui n'est pas celle posée ici.
Kevin B
@KevinB selon mon explication, j'ai importé un fichier .json dans un fichier .js. Cela m'a aidé à charger le fichier json dans const json. À partir de là, je peux utiliser le dictionnaire json suivant pour les attributs utilisateur, etc.
Ank_247shbm
C'est génial, cependant, cette question concerne un utilisateur essayant de copier un littéral d'objet dans un fichier .json qu'il charge ensuite avec ajax, seulement, leur littéral d'objet était dans un format qui n'était pas valide pour JSON. Bien que l'installation de react et son importation avec require fonctionneraient certainement dans certains cas, cela n'aide pas vraiment ce cas.
Kevin B
À noter: publier des commentaires liés à cette réponse sur toutes les autres réponses peut être considéré comme une auto-promotion excessive, et tenter de modifier les réponses est du vandalisme. Vos commentaires ont été supprimés et veuillez ne plus apporter de modifications de ce genre.
Brad Larson