Carregar o arquivo JSON local na variável

113

Estou tentando carregar um arquivo .json em uma variável em javascript, mas não consigo fazer funcionar. Provavelmente é apenas um pequeno erro, mas não consigo encontrar.

Tudo funciona bem quando uso dados estáticos como este:

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

Coloquei tudo o que está em {}um content.jsonarquivo e tentei carregá-lo em uma variável JavaScript local, conforme explicado aqui: load json into variable .

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

Eu o executei com o depurador do Chrome e ele sempre me diz que o valor da variável jsoné null. O content.jsonarquivo reside no mesmo diretório do arquivo .js que o chama.

O que eu perdi?

PogoMips
fonte
1
O url do seu arquivo é o /content.jsonque significa que o arquivo está no nível raiz do seu aplicativo da web. Mude para content.json(sem barra) para apontá-lo no mesmo diretório onde seu arquivo de script está colocado. Apenas no caso de seu arquivo de script estar no diretório de nível raiz, ele funcionará.
Samich
o arquivo reside em WebContent \ jit \ content.json .. Eu tentei 'url': "/WebContent/jit/content.json", mas ainda a variável é nula
PogoMips

Respostas:

38

Se você colou seu objeto content.jsondiretamente, ele é JSON inválido. Chaves e valores JSON devem ser colocados entre aspas duplas ( "não '), a menos que o valor seja numérico, booleano nullou composto (matriz ou objeto). JSON não pode conter funções ou undefinedvalores. Abaixo está o seu objeto como JSON válido.

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

Você também teve um extra }.

Kevin B
fonte
1
Eu não posso acreditar que corrigiu isso .. por que funcionaria diretamente embutido no arquivo .js sem aspas duplas, mas não no arquivo .json? Isso não faz sentido ...
PogoMips
16
@ user1695165 - json e um objeto javascript são duas coisas diferentes, eles têm a mesma aparência.
adeneo
2
@Kevin B "... a menos que o valor seja numérico [ou booleano]."
Jacob Beauchamp
1
Apenas uma dica: você pode usar um validador json como jsonlint.com para verificar seus dados json antes de usá-lo.
Marco Panichi
129

Minha solução, conforme respondida aqui , é usar:

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

O arquivo é carregado apenas uma vez, outras solicitações usam o cache.

editar Para evitar o armazenamento em cache, aqui está a função auxiliar desta postagem do blog fornecida nos comentários, usando o fsmódulo:

var readJson = (path, cb) => {
  fs.readFile(require.resolve(path), (err, data) => {
    if (err)
      cb(err)
    else
      cb(null, JSON.parse(data))
  })
}
Ehvince
fonte
48
Só queria especificar que essa solução requer uma biblioteca adicional chamada RequireJS .
Luis Kabongo
4
Como evitar o cache?
exceto
2
Não recomendado conforme Guilherme Oenning goenning.net/2016/04/14/stop-reading-json-files-with-require
Sangimed
2
TLDR; o cache o atingiu em testes de unidade e então ele deu uma função auxiliar para evitar o cache (ping @nono).
Ehvince
@Ehvince Oh não percebi isso, pois não li o artigo inteiro. Obrigado :-)
Sangimed
50

Para ES6 / ES2015 você pode importar diretamente como:

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


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

Se você usa Typescript, pode declarar o módulo json como:

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

Desde Typescript 2.9+ você pode adicionar - resolveJsonModule compilerOptions emtsconfig.json

{
  "compilerOptions": {
    "target": "es5",
     ...
    "resolveJsonModule": true,
     ...
  },
  ...
}
Little Roys
fonte
5
a importação não está funcionando no Chrome v72 - aindaUncaught SyntaxError: Unexpected token *
1000 Gbps de
2
Quando eu uso isso, parece dataum módulo, mas data.defaulté o objeto
Dustin Michels
1
Eu estava tentando rodar no console, mas sem sucesso. Isso não funciona com o nó v12.4.0, com o nó babel 6.26.0. Eu sempre consigoSyntaxError: Unexpected token *
mario199
2
para ES6 / ES2015 você pode importar diretamente: Parece que recebo um erro de console ao fazer import * as data from './example.json'devido a um erro de tipo mime.
Fallenreaper
se eu usar import * as data from './example.json';então dataé apenas módulo, mas data.defaulté o objeto. Mas quando eu uso import data from './example.json';, em seguida, dataé o objeto, que é mais applicapable
Nel
4

Existem dois problemas possíveis:

  1. AJAX é assíncrono, portanto, jsonserá indefinido quando você retornar da função externa. Quando o arquivo for carregado, a função de retorno de chamada será definida jsonpara algum valor, mas naquele momento, ninguém se importa mais.

    Vejo que você tentou consertar isso com 'async': false. Para verificar se isso funciona, adicione esta linha ao código e verifique o console do seu navegador:

    console.log(['json', json]);
  2. O caminho pode estar errado. Use o mesmo caminho que você usou para carregar seu script no documento HTML. Então, se o seu script for js/script.js, usejs/content.json

    Alguns navegadores podem mostrar quais URLs eles tentaram acessar e como isso aconteceu (códigos de sucesso / erro, cabeçalhos HTML, etc). Verifique as ferramentas de desenvolvimento do seu navegador para ver o que acontece.

Aaron Digulla
fonte
Talvez sua versão do jquery não suporte isso, ainda? Eu melhorei o texto.
Aaron Digulla
4

O módulo node.js integrado fs fará isso de forma assíncrona ou síncrona, dependendo de suas necessidades.

Você pode carregá-lo usando var fs = require('fs');

Assíncrono

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

Síncrono

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

Para o formato json fornecido como no arquivo ~ / my-app / src / db / abc.json:

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

para importar para um arquivo .js como ~ / 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;

Resultado:

Ankit Aditi Avani
Ank_247shbm
fonte
Esta é uma resposta a uma pergunta que não é a feita aqui.
Kevin B de
@KevinB de acordo com minha explicação, importei um arquivo .json para um arquivo .js. Isso me ajudou a carregar o arquivo json para const json. A partir daqui, posso usar o seguinte dicionário json para atributos de usuário e assim.
Ank_247shbm
Isso é ótimo, no entanto, esta pergunta é sobre um usuário tentando copiar um literal de objeto em um arquivo .json que então carrega com ajax, apenas, seu literal de objeto estava em um formato que não era válido para JSON. Apesar de instalar o react e importar isto com require certamente funcionaria em alguns casos, realmente não ajuda neste caso.
Kevin B de
Como observação: postar comentários com links para esta resposta em todas as outras respostas pode ser considerado autopromoção excessiva, e tentar editar as respostas é vandalismo. Seus comentários foram removidos e não faça edições como esta novamente.
Brad Larson
Obrigado é um ótimo trabalho para mim!
Qui-Gon Jinn