Artigo original: https://www.freecodecamp.org/news/json-stringify-example-how-to-parse-a-json-object-with-javascript/
O JSON, ou JavaScript Object Notation, está em todo o lugar. Se você já usou um aplicativo da web, há uma boa chance de você já ter usado o JSON para estruturar, armazenar e transmitir dados entre os servidores e o seu dispositivo.
Neste artigo, examinaremos brevemente as diferenças entre JSON e JavaScript. Depois, passaremos às diferenças entre fazer o parsing de JSON com JavaScript no navegador e em projetos do Node.js.
Diferenças entre JSON e JavaScript
Embora o JSON pareça JavaScript comum, é melhor pensar em JSON como um tipo de formato, semelhante a um arquivo de texto. O JSON é, sim, inspirado na sintaxe do JavaScript, razão pela qual eles se parecem tanto.
Vamos ver alguns objetos e arrays em JSON e compará-los com seus equivalentes em JavaScript.
Objetos em JSON x objetos literais em JavaScript
Primeiro, vamos ver um objeto em JSON:
{
"name": "Jane Doe",
"favorite-game": "Stardew Valley",
"subscriber": false
}
A diferença principal entre um objeto em JSON e um objeto comum em JavaScript – também chamado de objeto literal – está nas aspas. Todas as chaves e valores do tipo string em um objeto em JSON têm de estar cercados por aspas duplas("
).
Os objetos literais em JavaScript são um pouco mais flexíveis. Com eles, você não precisa cercar as chaves e strings com aspas duplas. Em vez disso, pode usar aspas simples ('
) ou simplesmente não usar aspas para as chaves.
Aqui temos o código acima em um objeto literal em JavaScript:
const profile = {
name: 'Jane Doe',
'favorite-game': 'Stardew Valley',
subscriber: false
}
Observe que a chave 'favorite-game'
está cercada por aspas simples. Com objetos literais, você precisa envolver as chaves quando as palavras forem separadas por hifens (-
).
Se você quisesse evitar as aspas, poderia reescrever a chave usando "camel case" (favoriteGame
) ou separar as palavras com uma sublinha (favorite_game
).
Arrays em JSON x arrays em JavaScript
Os arrays em JSON se parecem muito com os arrays em JavaScript, podendo conter strings, booleanos, números e outros objetos em JSON. Por exemplo:
[
{
"name": "Jane Doe",
"favorite-game": "Stardew Valley",
"subscriber": false
},
{
"name": "John Doe",
"favorite-game": "Dragon Quest XI",
"subscriber": true
}
]
Ele teria essa aparência em JavaScript simples:
const profiles = [
{
name: 'Jane Doe',
'favorite-game': 'Stardew Valley',
subscriber: false
},
{
name: 'John Doe',
'favorite-game': 'Dragon Quest XI',
subscriber: true
}
];
JSON como uma string
Você pode estar se perguntando: se existem objetos e arrays em JSON, não seria possível usá-los em seu programa como um objeto literal ou um array de JavaScript comuns?
O motivo de isso não ser possível é o fato de que o JSON é, de fato, apenas uma string.
Por exemplo, quando você escreve em JSON em um arquivo separado, como em jane-profile.json
ou profiles.json
acima, aquele arquivo de fato contém texto na forma de um objeto ou array de JSON, que, por acaso, se parece com JavaScript.
Se você fizer uma solicitação para uma API, ela retornará algo assim:
{"name":"Jane Doe","favorite-game":"Stardew Valley","subscriber":false}
Assim como ocorre com arquivos de texto, se você quiser usa o JSON em seu projeto, precisará fazer o parsing ou mudá-lo para algo que sua linguagem de programação possa entender. Por exemplo, fazer o parsing de um objeto em JSON em Python criará um dicionário.
Com isso em mente, vamos examinar maneiras diferentes de fazer o parsing de JSON em JavaScript.
Como fazer o parsing de JSON no navegador
Se estiver trabalhando com JSON no navegador, provavelmente estará recebendo ou enviando dados por uma API.
Vamos ver alguns exemplos.
Como fazer o parsing de JSON com fetch
A maneira mais fácil de se obter dados de uma API é com fetch
, que inclui o método .json()
para fazer o parsing das respostas em JSON em um objeto literal ou array utilizável em JavaScript "automagicamente".
Aqui temos um código que utiliza o fetch
para fazer uma solicitação de GET
para obter uma piada temática de desenvolvimento com a API gratuita de piadas sobre Chuck Norris:
fetch('https://api.chucknorris.io/jokes/random?category=dev')
.then(res => res.json()) // o método .json() faz o parsing da resposta em JSON para um objeto literal em JS
.then(data => console.log(data));
Se rodar esse código no navegador, verá algo assim impresso no console:
{
"categories": ["dev"],
"created_at": "2020-01-05 13:42:19.324003",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "elgv2wkvt8ioag6xywykbq",
"updated_at": "2020-01-05 13:42:19.324003",
"url": "https://api.chucknorris.io/jokes/elgv2wkvt8ioag6xywykbq",
"value": "O teclado de Chuck Norris não tem a tecla Ctrl porque nada controla Chuck Norris."
}
Embora isso pareça um objeto em JSON, é de fato um objeto literal em JavaScript. Você pode utilizá-lo com liberdade em seu programa.
Como transformar o JSON em string com JSON.stringify()
E se você quiser enviar dados para uma API?
Por exemplo, digamos que você queira enviar uma piada sobre Chuck Norris à API de piadas de Chuck Norris para que outras pessoas possam ler mais tarde.
Primeiro, você precisa escrever sua piada como um objeto literal em JS:
const newJoke = {
categories: ['dev'],
value: "O teclado de Chuck Norris é feito apenas de teclas Cmd porque Chuck Norris está sempre no comando."
};
Depois, como você está enviando dados para uma API, precisa transformar seu novo objeto literal newJoke
em uma string em JSON.
Por sorte, o JavaScript inclui um método muito útil que faz exatamente isso – JSON.stringify()
:
const newJoke = {
categories: ['dev'],
value: "O teclado de Chuck Norris é feito apenas de teclas Cmd porque Chuck Norris está sempre no comando."
};
console.log(JSON.stringify(newJoke)); // {"categories":["dev"],"value":"O teclado de Chuck Norris é feito apenas de teclas Cmd porque Chuck Norris está sempre no comando."}
console.log(typeof JSON.stringify(newJoke)); // string
Embora estejamos convertendo um objeto literal em uma string em JSON neste exemplo, JSON.stringify()
também funciona com arrays.
Por fim, você só precisa enviar sua piada transformada em uma string em JSON de volta para a API com uma solicitação de POST
.
Observe que a API de piadas de Chuck Norris não tem, de fato, esse recurso. Se tivesse, o código para enviar para ela uma piada teria essa aparência:
const newJoke = {
categories: ['dev'],
value: "O teclado de Chuck Norris é feito apenas de teclas Cmd porque Chuck Norris está sempre no comando."
};
fetch('https://api.chucknorris.io/jokes/submit', { // endpoint falso de API
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newJoke), // transforma o objeto literal em JS em uma string em JSON
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => {
console.error(err);
});
E assim, você fez o parsing de uma JSON de entrada com fetch
e usou JSON.stringify()
para converter um objeto literal em JS em uma string em JSON.
Como trabalhar com arquivos locais em JSON no navegador
Infelizmente, não é possível (nem aconselhável) carregar um arquivo JSON local no navegador.
fetch
lançará um erro se tentar carregar um arquivo local. Por exemplo, digamos que você tenha um arquivo JSON com algumas piadas:
[
{
"categories": ["dev"],
"created_at": "2020-01-05 13:42:19.324003",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "elgv2wkvt8ioag6xywykbq",
"updated_at": "2020-01-05 13:42:19.324003",
"url": "https://api.chucknorris.io/jokes/elgv2wkvt8ioag6xywykbq",
"value": "O teclado de Chuck Norris não tem a tecla Ctrl porque nada controla Chuck Norris."
},
{
"categories": ["dev"],
"created_at": "2020-01-05 13:42:19.324003",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "ae-78cogr-cb6x9hluwqtw",
"updated_at": "2020-01-05 13:42:19.324003",
"url": "https://api.chucknorris.io/jokes/ae-78cogr-cb6x9hluwqtw",
"value": "Não existe tecla Esc no teclado de Chuck Norris, porque ninguém escapa de Chuck Norris."
}
]
E que você quer fazer o parsing do arquivo e criar uma lista de piadas em uma página simples de HTML.
Se você criar uma página com o código abaixo e abri-la em seu navegador:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width" />
<title>Fetch Local JSON</title>
</head>
<script>
fetch("./jokes.json", { mode: "no-cors" }) // disable CORS because path does not contain http(s)
.then((res) => res.json())
.then((data) => console.log(data));
</script>
</html>
Você verá isso no console:
Fetch API cannot load file://<path>/jokes.json. URL scheme "file" is not supported
Por padrão, os navegadores não permitem acesso aos arquivos locais por motivos de segurança. Isso é bom, e você não precisa tentar achar uma forma de contornar esse comportamento.
Em vez disso, o melhor a fazer é converter o arquivo JSON local em JavaScript. Por sorte, é bem fácil, já que a sintaxe do JSON é semelhante à do JavaScript.
Tudo o que você precisa fazer é criar um novo arquivo e declarar seu JSON como uma variável:
const jokes = [
{
"categories": ["dev"],
"created_at": "2020-01-05 13:42:19.324003",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "elgv2wkvt8ioag6xywykbq",
"updated_at": "2020-01-05 13:42:19.324003",
"url": "https://api.chucknorris.io/jokes/elgv2wkvt8ioag6xywykbq",
"value": "O teclado de Chuck Norris não tem a tecla Ctrl porque nada controla Chuck Norris."
},
{
"categories": ["dev"],
"created_at": "2020-01-05 13:42:19.324003",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "ae-78cogr-cb6x9hluwqtw",
"updated_at": "2020-01-05 13:42:19.324003",
"url": "https://api.chucknorris.io/jokes/ae-78cogr-cb6x9hluwqtw",
"value": "Não existe tecla Esc no teclado de Chuck Norris, porque ninguém escapa de Chuck Norris."
}
]
Além disso, adicione-o à sua página como um script separado:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width" />
<title>Fetch Local JSON</title>
</head>
<script src="jokes.js"></script>
<script>
console.log(jokes);
</script>
</html>
Você conseguirá usar o array jokes
livremente em seu código.
Você também pode usar os modules
de JavaScript para fazer a mesma coisa, mas isso fica um pouco fora do escopo deste artigo.
E se você quiser trabalhar com arquivos JSON locais e tiver instalado o Node.js? Vamos dar uma olhada em como fazer isso agora.
Como fazer o parsing de JSON no Node.js
O Node.js é um executável de JavaScript que permite que você rode JavaScript fora do navegador. Você pode ler tudo sobre o Node.js aqui (em inglês).
Seja usando o Node.js para rodar código no local em seu computador ou executando aplicações inteiras da web em um servidor, é bom saber como trabalhar com JSON.
Para os exemplos a seguir, usaremos o mesmo arquivo jokes.json
:
[
{
"categories": ["dev"],
"created_at": "2020-01-05 13:42:19.324003",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "elgv2wkvt8ioag6xywykbq",
"updated_at": "2020-01-05 13:42:19.324003",
"url": "https://api.chucknorris.io/jokes/elgv2wkvt8ioag6xywykbq",
"value": "O teclado de Chuck Norris não tem a tecla Ctrl porque nada controla Chuck Norris."
},
{
"categories": ["dev"],
"created_at": "2020-01-05 13:42:19.324003",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "ae-78cogr-cb6x9hluwqtw",
"updated_at": "2020-01-05 13:42:19.324003",
"url": "https://api.chucknorris.io/jokes/ae-78cogr-cb6x9hluwqtw",
"value": "Não existe tecla Esc no teclado de Chuck Norris, porque ninguém escapa de Chuck Norris."
}
]
Como fazer o parsing de um arquivo JSON com require()
Vamos começar com o método mais fácil.
Se você tem um arquivo JSON local, tudo o que precisa fazer é usar require()
para carregá-lo como qualquer outro módulo de Node.js:
const jokes = require('./jokes.json');
Será feito o parsing do arquivo JSON para você automaticamente e você poderá começar a usá-lo no seu projeto:
const jokes = require('./jokes.json');
console.log(jokes[0].value); // "O teclado de Chuck Norris não tem a tecla Ctrl porque nada controla Chuck Norris."
Observe que isso ocorre de modo síncrono, o que significa que seu programa vai permanecer parado até que faça o parsing do arquivo inteiro antes de continuar. Arquivos JSON muito grandes podem causar a lentidão do programa, portanto tenha cuidado com isso.
Além disso, como fazer o parsing de JSON dessa forma carrega tudo dentro da memória, é melhor usar esse método para arquivos JSON estáticos. Se o arquivo JSON mudar enquanto seu programa está em execução, você não terá acesso a essas mudanças até reiniciar o programa e fazer o parsing do arquivo JSON atualizado.
Como fazer o parsing de um arquivo JSON com fs.readFileSync(
) e JSON.parse()
Essa é a maneira mais tradicional (na falta de uma palavra melhor) para fazer o parsing JSON em projetos do Node.js – ler o arquivo com o módulo fs
(file system), e depois fazer o parsing com JSON.parse()
.
Vejamos como fazer isso com o método fs.readFileSync()
. Primeiro, adicione o módulo fs
ao seu projeto:
const fs = require('fs');
Depois, crie uma nova variável para armazenar o resultado do arquivo jokes.json
e defini-lo como igual a fs.readFileSync()
:
const fs = require('fs');
const jokesFile = fs.readFileSync();
fs.readFileSync()
recebe dois argumentos. O primeiro é o caminho do arquivo que você quer ler:
const fs = require('fs');
const jokesFile = fs.readFileSync('./jokes.json');
Porém, se você imprimir jokesFile
no console agora, verá algo assim:
<Buffer 5b 0a 20 20 7b 0a 20 20 20 20 22 63 61 74 65 67 6f 72 69 65 73 22 3a 20 5b 22 64 65 76 22 5d 2c 0a 20 20 20 20 22 63 72 65 61 74 65 64 5f 61 74 22 3a ... 788 more bytes>
Isso significa apenas que o módulo fs
está lendo o arquivo, mas não sabe a codificação ou o formato no qual o arquivo está. O fs
pode ser usado para carregar quase todos os arquivos, não apenas aqueles baseados em texto, como o JSON. Por isso, precisamos dizer a ele como o arquivo está codificado.
Para arquivos baseados em texto, a codificação normalmente é a utf8
:
const fs = require('fs');
const jokesFile = fs.readFileSync('./jokes.json', 'utf8');
Agora, se você imprimir jokesFile
no console, verá os conteúdos do arquivo.
Até o momento, porém, estamos apenas lendo o arquivo, e ele ainda é uma string. Precisaremos usar outro método para fazer o parsing de jokesFile
, transformando-o em um objeto ou array de JavaScript utilizável.
Para fazer isso, usaremos JSON.parse()
:
const fs = require('fs');
const jokesFile = fs.readFileSync('./jokes.json', 'utf8');
const jokes = JSON.parse(jokesFile);
console.log(jokes[0].value); // "O teclado de Chuck Norris não tem a tecla Ctrl porque nada controla Chuck Norris."
Como o nome sugere, JSON.parse()
recebe uma string em JSON e faz seu parsing para um objeto literal ou array em JavaScript.
Assim como no método require
acima, fs.readFileSync()
é um método síncrono, o que significa que ele faria com que seu programa ficasse mais lento se estivesse lendo um arquivo grande, JSON ou não.
Além disso, ele somente lê o arquivo uma vez e o carrega na memória. Se o arquivo mudar, você precisará ler o arquivo novamente em algum momento. Para tornar as coisas mais fáceis, você pode criar uma função simples para ler arquivos.
Uma função como essa teria a seguinte aparência:
const fs = require('fs');
const readFile = path => fs.readFileSync(path, 'utf8');
const jokesFile1 = readFile('./jokes.json');
const jokes1 = JSON.parse(jokesFile1);
console.log(jokes1[0].value); // "O teclado de Chuck Norris não tem a tecla Ctrl porque nada controla Chuck Norris."
// o arquivo jokes.json é alterado em algum momento
const jokesFile2 = readFile('./jokes.json');
const jokes2 = JSON.parse(jokesFile2);
console.log(jokes2[0].value); // "O teclado de Chuck Norris é feito apenas de teclas Cmd porque Chuck Norris está sempre no comando."
Como fazer o parsing de JSON com fs.readFile(
) e JSON.parse()
O método fs.readFile()
é bastante semelhante ao fs.readFileSync()
, exceto pelo fato de funcionar de modo assíncrono. Isso é ótimo se você tiver um grande arquivo para ler e se não quiser fazer com que todo o resto do código espere pela leitura.
Aqui está um exemplo básico:
const fs = require('fs');
fs.readFile('./jokes.json', 'utf8');
Ate agora, parece bastante semelhante ao que fizemos com fs.readFileSync()
, exceto por não estarmos atribuindo a uma variável como jokesFile
. Como ele é assíncrono, qualquer código após fs.readFile()
será executado antes de ele ter concluído a leitura do arquivo.
Em vez disso, usaremos uma função de callback e faremos o parsing do arquivo JSON dentro dela:
const fs = require('fs');
fs.readFile('./jokes.json', 'utf8', (err, data) => {
if (err) console.error(err);
const jokes = JSON.parse(data);
console.log(jokes[0].value);
});
console.log("Isso rodará primeiro!");
O que imprime o seguinte no console:
Isso rodará primeiro
O teclado de Chuck Norris não tem a tecla Ctrl porque nada controla Chuck Norris.
Como ocorre com fs.readFileSync()
, fs.readFile()
carrega o arquivo na memória, o que significa que você precisa ler o arquivo novamente se ele mudar.
Além disso, mesmo que fs.readFile()
seja assíncrono, ele eventualmente carregará todo o arquivo que está lendo na memória. Se o arquivo for muito grande, pode ser melhor você buscar saber sobre streams em Node.js (texto em inglês) como opção.
Como transformar os dados em uma string JSON com JSON.stringify()
no Node.js
Por fim, se fizer o parsing JSON com Node.js, há uma boa chance de você precisar retornar o JSON em algum momento, talvez como uma resposta da API.
Por sorte, isso funciona da mesma maneira que no navegador – basta usar JSON.stringify()
para converter os objetos literais ou arrays de JavaScript em uma string em JSON:
const newJoke = {
categories: ['dev'],
value: "O teclado de Chuck Norris é feito apenas de teclas Cmd porque Chuck Norris está sempre no comando."
};
console.log(JSON.stringify(newJoke)); // {"categories":["dev"],"value":"O teclado de Chuck Norris é feito apenas de teclas Cmd porque Chuck Norris está sempre no comando."}
Era isso! Tratamos de tudo o que você precisa saber sobre trabalhos com JSON no navegador e em projetos de Node.js.
Agora é sua vez. Faça o parsing ou stringify de JSON daquilo que você deseja.
O autor deixou escapar algo? Como você faz o parsing de JSON em seus projetos? Conte para ele pelo Twitter.