Webpack not parsing JSON - json

I'm trying to load a JSON file into my ReactJS application, but any of the following methods I've tried the following:
Require:
const countries =require('../../json/countries.json');
// Also fails the exact same way with redundant parse call:
const countries = JSON.parse(require('../../json/countries.json'));
Importing using json-loader:
import countries from '../../json/countries.json';
Using the following loader in loaders
{
test: /\.json$/,
loader: 'json-loader'
}
The JSON loads, but fails to parse:
./src/app/json/countries.json
Module build failed: SyntaxError: /src/app/json/countries.json:
Unexpected token, expected ; (2:6)
1 | {
> 2 | "BD": "Bangladesh",
| ^
3 | "BE": "Belgium",
4 | "BF": "Burkina Faso",
5 | "BG": "Bulgaria",
The countries.json file is valid JSON downloaded from http://country.io, but it seems the quotes are causing an issue. But this is valid JSON being loaded by JavaScript, so it should work together seamlessly.
Any idea what the problem is?
SOLVED
I solved this issue by changing the loader directive into use:
let config = {
module: {
loaders: [
...
{
test: /\.json$/,
use: {
loader: 'json-loader'
}
}
]
}
};

You are loading a json file already, no need to parse it.
If it was a string you could parse it.
Here is a small example to demonstrate the difference:
const json = {
"BD": "Bangladesh",
"BE": "Belgium",
"BF": "Burkina Faso",
"BG": "Bulgaria"
}
const strJson = `{
"BD": "Bangladesh",
"BE": "Belgium",
"BF": "Burkina Faso",
"BG": "Bulgaria"
}`
console.log('string parsed to a json',JSON.parse(strJson));
console.log('regular json',json);

Related

Why does my TS file thinks a JSON array is an object?

I'm trying to import a really large JSON file inside a TypeScript file. When I use it my IDE tells me that Property 'length' does not exist on type '{}', when the JSON is clearly an array. How could I fix this?
This is my code:
TS file:
import cities from "./cities.json"
const printData = () => {
console.log(cities.length)
}
JSON file:
[
{ "country": "Andorra", "name": "Sant Julià de Lòria" },
{ "country": "Andorra", "name": "Pas de la Casa" },
{ "country": "Andorra", "name": "Ordino" },
{ "country": "Andorra", "name": "les Escaldes" },
{ "country": "Andorra", "name": "la Massana" },
{ "country": "Andorra", "name": "Encamp" },
... + 128K more objects
]
I've seen that it can come from the size of the file, and that I should use a .d.ts file to declare it. I tried this:
let cities: {
country: string
name: string
}[]
export declare module "./cities.json" {
cities
}
But to call the object I need to call it twice like this:
import cities from "./cities"
const printData = () => {
console.log(cities.cities.length)
}
How could I fix this? Thanks!
Actually, I think this approach is useful. The only thing that you could change is the way that you are importing the information. You can destructure the object that you are importing.
Before:
import cities from "./cities"
After
import {cities} from "./cities"
With that you can use cities.length with no hesitation!
You can use object destructuring to get cities out of cities. For a simple one-liner solution, use this code.
import { cities } from "./cities";
This means that you can use only one cities for getting the length!
cities.length;
This will solve your issue, and also increase code readability.

Import JSON file in React with data format error

I tried to import a JSON file in my React project, but got the parsing error:
json file:testData.json
{
"data": {
"articles": [
{
"id": "95c12a8f6c88953ca8f8a39da25546e6",
"title": "Introducing React's Error Code System",
"date": "Mon Jul 11 2016 00:00:00 GMT+0000 (UTC)",
"authorId": "2c6aa2cfe3449467d329fa17d6ea230f",
"body": "Building a better developer experience has been one of the things that React deeply cares about, and a crucial part of it is to detect anti-patterns/potential errors early and provide helpful error messages when things (may) go wrong. However, most of these only exist in development mode; in production, we avoid having extra expensive assertions and sending down full error messages in order to reduce the number of bytes sent over the wire."
}
],
"authors": [
{
"id": "d85577ea34ae50f2dac5347b5219aa23",
"firstName": "Andrew",
"lastName": "Clark",
"website": "https://twitter.com/acdlite"
}
]
}
}
DataApi.js file:
export default class DataApi {
// property: rawData
constructor(rawData) {
this.rawData = rawData;
}
mapIntoObject(arr) {
return arr.reduce((acc, curr) => {
acc[curr.id] = curr;
return acc;
}, {});
}
getArticle() {
return this.mapIntoObject(this.rawData.articles);
}
getAuthors() {
return this.mapIntoObject(this.rawData.authors);
}
}
And I tried to import JSON data in this file:
import DataApi from "./DataApi"; // object to process data
import { data } from "./testData.json"; // raw data
// create a api object to host raw data
let api = new DataApi(data);
const articles = api.getArticle();
console.log(articles);
then I got the error:(the import directory are correct):
2:13 error Parsing error: Unexpected token, expected ";"
1 | {
> 2 | "articles": [
| ^
3 | {
4 | "id": "95c12a8f6c88953ca8f8a39da25546e6",
5 | "title": "Introducing React's Error Code System",
What is the problem?
You can do export default
testData.json:
const data = {
"data": {
"articles": [
{
"id": "95c12a8f6c88953ca8f8a39da25546e6",
"title": "Introducing React's Error Code System",
"date": "Mon Jul 11 2016 00:00:00 GMT+0000 (UTC)",
"authorId": "2c6aa2cfe3449467d329fa17d6ea230f",
"body": "Building a better developer experience has been one of the things that React deeply cares about, and a crucial part of it is to detect anti-patterns/potential errors early and provide helpful error messages when things (may) go wrong. However, most of these only exist in development mode; in production, we avoid having extra expensive assertions and sending down full error messages in order to reduce the number of bytes sent over the wire."
}
],
"authors": [
{
"id": "d85577ea34ae50f2dac5347b5219aa23",
"firstName": "Andrew",
"lastName": "Clark",
"website": "https://twitter.com/acdlite"
}
]
}
}
export default data;
and while importing
With json-loader installed, you can use
import data from "./testData.json";
or If you have used create-react-app to scaffold your project, the module is already included, you just need to import your json:
import data from "./testData";
To install json-loader
npm install --save-dev json-loader
And add below config to your webpack.config.js
webpack.config.js
module.exports = {
module: {
loaders: [
{
test: /\.json$/,
loader: 'json-loader'
}
]
}
}
You have to export your json data, your json data should be like this.
export const data = {
"data": {
"articles": [
{
"id": "95c12a8f6c88953ca8f8a39da25546e6",
"title": "Introducing React's Error Code System",
"date": "Mon Jul 11 2016 00:00:00 GMT+0000 (UTC)",
"authorId": "2c6aa2cfe3449467d329fa17d6ea230f",
"body": "Building a better developer experience has been one of the things that React deeply cares about, and a crucial part of it is to detect anti-patterns/potential errors early and provide helpful error messages when things (may) go wrong. However, most of these only exist in development mode; in production, we avoid having extra expensive assertions and sending down full error messages in order to reduce the number of bytes sent over the wire."
}
],
"authors": [
{
"id": "d85577ea34ae50f2dac5347b5219aa23",
"firstName": "Andrew",
"lastName": "Clark",
"website": "https://twitter.com/acdlite"
}
]
}
}
change .json to .js extention, while importing
import { data } from "./testData"; // raw data

CSV to JSON and add title

I have a csv document:
{
"epsilon_id": 194029423,
"weather": "cloudy",
"temperature": 27
},
{
"epsilon_id": 932856192,
"weather": "sunny",
"temperature": 31
}
I was wondering if there was a tool to make it into valid json where the field epsilon_id is the title for the data.
ex:
{
194029423: {
"weather": "cloudy",
"temperature": 27
},
932856192: {
"weather": "sunny",
"temperature": 31
}
}
I would prefer it to be a program (in whatever language) that I can run because I have 1,000 entries in my test sample and I will have tens of thousands in my final copy.
Any help would be much appreciated!
You are looking at JSON transformation, and ofcourse can be achieved with a custom programming. I can explain you how you can achieve this in Java, but functionally its gonna be the same for any programming of your choice.
Your input json will look like this:
[{
"epsilon_id": 194029423,
"weather": "cloudy",
"temperature": 27
},
{
"epsilon_id": 932856192,
"weather": "sunny",
"temperature": 31
}]
When you parse in java using popular Jackson library, you will get list of object for below class:
class Input
{
#JsonProperty(access = Access.WRITE_ONLY)
String epsilon_id,
String weather,
int temperature
}
Then you create a map object Map<Integer, Input>, populate data like below:
Map<Integer, Input> map = new HashMap<>();
for(Input obj : listOfInputs){
map.put(obj.epsilon_id, obj)
};
Serialize your result map using Jackson again to get your desired output format:
{
194029423: {
"weather": "cloudy",
"temperature": 27
},
932856192: {
"weather": "sunny",
"temperature": 31
}
}
If you are not very familiar with Java & Jackson JSON parsing, I found this tutorial with code sample, which will give you headstart.
import csv, json, os
# rename this file or pass it in as process.argv[2]
# then pipe output into another file. or
with open("./foo.csv") as f:
output = {}
for line in csv.DictReader(f):
key = line.pop("epsilon_id")
if output.has_key(key):
print("Duplicate Id -> {} ".format(key))
output[key] = line
# then pipe this output into another file.
print(json.dumps(output, indent=2))
# or write a file
with open("/tmp/foo.json",'w') as f:
json.dump(output, f)
Python makes it pretty easy : this will detect all types from a csv file.
demo : https://repl.it/#markboyle/UsableIcyFeed

Retrieving data from json using AngularJS

I am learning angular js from ground up and am currently trying to retrieve data from a json file.
I am using - nodejs, express, AngularJS.
Earlier I was getting an error "Unexpected token D" on using -
$http.get("/models/driversList.json").success(function(response){$scope.driversList = response})
which got resolved but now I'm getting something like this with the current code -
Drivers Championship Standings
1
I'm guessing the response is basically blank and therefore the "1" but am not getting as to why that is happening.
Below are my files -
/app.js
app.use('/models',express.static(path.join(__dirname, 'private/data/db/models')));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/scripts',express.static(path.join(__dirname, 'public/javascripts')));
app.use('/styles',express.static(path.join(__dirname, 'public/stylesheets')));
/javascripts/app.js
angular.module('F1FeederApp', [
'F1FeederApp.controllers'
]);
/javascripts/controllers.js
angular.module('F1FeederApp.controllers', []).
controller('driversController', function($scope, $http) {
$http({
method: 'GET',
url: '/models/driversList.json',
data: {},
transformResponse: function (data, headersGetter, status) {
//This was implemented since the REST service is returning a plain/text response
//and angularJS $http module can't parse the response like that.
return {data: data};
}
}).success(function(response){ alert('worked'); $scope.driversList = response}).error(function(response) {
$scope.driversList = [
{
Driver: {
givenName: response,
familyName: 'Vettel'
},
points: 322,
nationality: "German",
Constructors: [
{name: "Red Bull"}
]
},
{
Driver: {
givenName: 'Fernando',
familyName: 'Alonso'
},
points: 207,
nationality: "Spanish",
Constructors: [
{name: "Ferrari"}
]
}
];
})
});
driversList.json
[
{
Driver: {
givenName: 'Eldorado',
familyName: 'Vettel'
},
points: 322,
nationality: "German",
Constructors: [
{name: "Red Bull"}
]
},
{
Driver: {
givenName: 'Fernando',
familyName: 'Alonso'
},
points: 207,
nationality: "Spanish",
Constructors: [
{name: "Ferrari"}
]
}
]
index.html
<!DOCTYPE html>
<html>
<head>
<title>F-1 Feeder</title>
<script src="/scripts/angular.min.js"></script>
<script src="/scripts/controllers.js"></script>
<script src="/scripts/app.js"></script>
</head>
<body ng-app="F1FeederApp" ng-controller="driversController">
<table>
<thead>
<tr><th colspan="4">Drivers Championship Standings</th></tr>
</thead>
<tbody>
<tr ng-repeat="driver in driversList">
<td>{{$index + 1}}</td>
<td>
{{driver.Driver.givenName}} {{driver.Driver.familyName}}
</td>
<td>{{driver.Constructors[0].name}}</td>
<td>{{driver.points}}</td>
</tr>
</tbody>
</table>
</body>
</html>
EDIT:
#rattanak
To answer the point 3, yes it works if I simply assign the array variable to the scope variable. The part in error() is the one which was working previously.
I also tried point 1 and it seems the json is present in "data", so I assigned response.data to driversList and now am getting this error -
Data:
[{Driver:{givenName:'Eldorado',familyName:'Vettel'},points:322,nationality:"German",Constructors:[{name:"Red Bull"}]}]
Error: [ngRepeat:dupes] http://errors.angularjs.org/1.4.7/ngRepeat/dupes?p0=driver%20in%20driversList.data&p1=string%3Ar&p2=r
at Error (native)
at http://localhost:3000/scripts/angular.min.js:6:416
at http://localhost:3000/scripts/angular.min.js:280:39
at Object.fn (http://localhost:3000/scripts/angular.min.js:129:401)
at n.a.$get.n.$digest (http://localhost:3000/scripts/angular.min.js:130:483)
at n.a.$get.n.$apply (http://localhost:3000/scripts/angular.min.js:133:512)
at h (http://localhost:3000/scripts/angular.min.js:87:376)
at K (http://localhost:3000/scripts/angular.min.js:91:499)
at XMLHttpRequest.z.onload (http://localhost:3000/scripts/angular.min.js:93:37)
indicating that there are duplicates
Your file driverlist.json does not contain valid JSON code. This code should be:
[
{
"Driver": {
"givenName": "Eldorado",
"familyName": "Vettel" },
"points": 322,
"nationality": "German",
"Constructors": [
{"name": "Red Bull"}
]
},
{
"Driver": {
"givenName": "Fernando",
"familyName": "Alonso"
},
"points": 207,
"nationality": "Spanish",
"Constructors": [
{"name": "Ferrari"}
]
}
]
Correct this and try again.
JSON always use double quotes (") never single quotes (')
For more info on correct JSON, see http://www.json.org/
It seems like the $http service does not resolve successfully. It is hard to tell without actually testing the code. With Chrome Dev Console, I would debug the code by:
Use console.log($scope.driversList) in the success function of the promise.
Use console.log(error) in the error function of the promise.
Were you able to get the code to work without using $http service, namely just assign array variable of the data to $scope.driversList.
I am happy to test it for you if you can provide a github link or something.

JSON Parsing Error

I got problem. I have this JSON automatically generated by Open Flash Chart php library. The problem is, OFC report JSON Parse Error [Syntax Error] while test result using http://www.jsonlint.com/ report that my JSON is fine. But, w3c parser report error too:(
Any help?
Here's the JSON:
{
"title": "Followers Trend",
"elements": [
{
"type": "area_hollow",
"fill-alpha": 0.35,
"values": [
],
"colour": "#5B56B6",
"text": "Followers",
"font-size": 12
}
],
"x_axis": {
"colour": "#A2ACBA",
"grid-colour": "#D7E4A3",
"offset": false,
"steps": 4,
"labels": {
"steps": 2,
"rotate": "vertical",
"colour": "#A2ACBA",
"labels": [
]
}
},
"x_legend": {
"text": "Week Trend (2009-08-17 - 2009-08-24)",
"style": "{font-size: 20px; color: #778877}"
},
"y_axis": {
"min": 0,
"max": 150,
"steps": 30
}
}
A few things I learned while playing with JSON is:
If you have validate the JSON on various JSON validation services and the result is GOOD. But, when you failed to eval it, try to wrap your JSON using ( and ) => ({jsondata})
var json = eval( "(" + jsonString + ")" );
NEVER build the JSON yourself. It's a gate to failure. Always use official or popular JSON library (depending on your language). For example:
On PHP: use json_encode()
On Java Android: use org.json.JSONObject
A list of all other available library to play with JSON is listed in JSON official page.
To display and format JSON data, you can use JSONViewer.
I think the w3c parser is having issues, I couldn't even get it to parse this:
{
"title" : "Followers Trend"
}
It gave me this error:
Validation errors:
lexer couldn't parse at "{
"title" : "Followers Trend"
}"
http://json.bloople.net helps you visualise the code to find and correct errors.
try this code, JSON.parse() method is not able to handle string which is in a
single quote as a value in the right-hand side. also if you want to handle the
UTF-8 character code, then it will do.
parseJSON = function() {
var data = {};
var reader = new FileReader();
reader.onload = function() {
try {
data = JSON.parse(reader.result.replace(/'/g, "\""));
console.log(data)
} catch (ex) {
console.log('error' + ex);
}
};
reader.readAsText(fileSelector_test[0].files[0], 'utf-8');
}