JavaScript - Error importing JSON that contains array of objects - javascript

I'm trying to import JSON file that contains an array of blog-posts. All data contained in JSON file is imported successfully, except the Array of objects (edges)
This code is part of a unit test created with JestJS for a site build with Gatsby.
When I try to access edges array, I get "TypeError: Cannot read property 'edges' of undefined".
JS code:
import data from "./__mocks__/blog.json";
console.log(data);
data.allMarkdownRemark.edges.forEach((post) => {
console.log(post);
})
Console.log(data):
{ data: { allMarkdownRemark: { edges: [Array] } }
My JSON file is formatted as a JSON object, so it is not necessary to use JSON.parse()
JSON file:
{
"data": {
"allMarkdownRemark": {
"edges": [
{
"node": {
"id": "c60d0972-1f4a-55ae-b762-c24795fae501",
"fields": {
"slug": "/a-tu-cerebro-no-le-gusta-la-innovacion/"
},
"frontmatter": {
"title": "A tu cerebro no le gusta la Innovación",
"templateKey": "blog-post",
"date": "September 16, 2017"
}
}
},
{
"node": {
"id": "1624f260-4c77-55d3-8297-4f0ad688f878",
"fields": {
"slug": "/la-mente-es-para-tener-ideas-no-para-almacenarlas/"
},
"frontmatter": {
"title": "La mente es para tener Ideas™, no para almacenarlas",
"templateKey": "blog-post",
"date": "August 26, 2017"
}
}
}
]
}
}
}
Do you know how to import correctly "edges" array of objects from JSON file?

The problem is your variable is called data and inside your json file you also defined data as a key. So you have to use data once as the variable and a second time as the key of the JSON file.
you have to access it like this:
data.data.allMarkdownRemark.edges.forEach((post) => {
console.log(post);
})
Another solution would be to change the structure of your JSON file.

You can:
import { data } from "./__mocks__/blog.json";

Related

I am having trouble appending dynamic data to my JSON file

I have been having a bit of trouble appending new dynamic data to a JSON file. To sum up my project, I take in the projectName from an input form at the /new page.
My API is then using the node.js's fs module to create a new JSON file with which I can then append the new dynamic data upon subsequential requests to my form. The variables are 1) projectName (is taken in from my form), 2) activeUser (which is programmed in through an environmental variable), 3) is the date of the request which I am acquiring through a timestamp variable with this function:
const timestamp = (JSON.parse(JSON.stringify(new Date())));
All three of these variables seem to print correctly for 2 subsequent requests and then on the third form submission there seems to be no new data appending to the JSON file. However i am relatively new to node.js and I can't seem to figure out where I am messing this up.
This is my API
pages/api/demos/index.js
import dbConnect from '../../../lib/dbConnect';
import Demo from '../../../models/Demo';
import fs from 'fs';
export default async function handler(req, res) {
const {
query: { id },
method,
} = req
await dbConnect()
switch (method) {
case 'POST':
try {
//check if file exist
if (!fs.existsSync('projects.json')) {
//create new file if not exist
fs.closeSync(fs.openSync('projects.json', 'w'));
}
// read file
const timestamp = (JSON.parse(JSON.stringify(new Date())));
const newFileName = req.body.projectName;
const activeUser = process.env.ACTIVE_USERNAME;
const file = fs.readFileSync('projects.json')
const data = {
"projects": [
{
"username": activeUser,
"pages": [
{
"display": "routes",
"subpages": [
{
"date": timestamp,
"route": newFileName,
"display": newFileName
}
]
}
]
}
]
}
//check if file is empty
if (file.length == 0) {
//add data to json file
fs.writeFileSync("projects.json", JSON.stringify([data]))
} else {
//append data to jso file
const json = JSON.parse(file.toString())
//add json element to json object
json.push(data);
fs.appendFileSync("projects.json", JSON.stringify(data))
}
const demo = await Demo.create(
req.body
)
res.status(201).json({ success: true, data: demo })
} catch (error) {
res.status(400).json({ success: false })
}
break
default:
res.status(400).json({ success: false })
break
}
}
After the first form submission my JSON file projects.json looks like
[
{
"projects": [
{
"username": "projectmikey",
"pages": [
{
"display": "routes",
"subpages": [
{
"date": "2022-09-12T19:03:09.547Z",
"route": "1",
"display": "1"
}
]
}
]
}
]
}
]
and then after the 2nd form submission
[
{
"projects": [
{
"username": "projectmikey",
"pages": [
{
"display": "routes",
"subpages": [
{
"date": "2022-09-12T19:03:09.547Z",
"route": "1",
"display": "1"
}
]
}
]
}
]
}
]{
"projects": [
{
"username": "projectmikey",
"pages": [
{
"display": "routes",
"subpages": [
{
"date": "2022-09-12T19:03:24.466Z",
"route": "2",
"display": "2"
}
]
}
]
}
]
}
Oddly it seems to work for two form submissions and then the data stops appending to my file. This is after the third attempt, (no change to the file)
[
{
"projects": [
{
"username": "projectmikey",
"pages": [
{
"display": "routes",
"subpages": [
{
"date": "2022-09-12T19:03:09.547Z",
"route": "1",
"display": "1"
}
]
}
]
}
]
}
]{
"projects": [
{
"username": "projectmikey",
"pages": [
{
"display": "routes",
"subpages": [
{
"date": "2022-09-12T19:03:24.466Z",
"route": "2",
"display": "2"
}
]
}
]
}
]
}
It seems to stop working at all when I remove the pair of brackets around the initial JSON object. The line I am refering to is fs.writeFileSync("projects.json", JSON.stringify([data]))
I could really use another pair of eyes on this so I can see where I am messing this up! lol Thanks in advance for your time...
Although it feels like you are "appending" to the file, you are actually doing something more complicated.
e.g. before state:
[ "one", "two" ]
desired after-state:
[ "one", "two", "three" ]
Notice that you can't just append text to the before-state JSON because there's already that pesky ] terminating the whole object.
Some failed attempts might look like:
failed attempt to append another entire array
[ "one", "two" ][ "three" ]
This is invalid because there are two root objects.
failed attempt to append just the rest of the array
[ "one", "two" ], "three" ]
That's no good either. The ] at the end of the original file needs to be overwritten or removed, so there's no way to just append. I suppose technically you could seek to the position of the final ] and then continue writing an incomplete object from there. But this is very awkward to remove the final ] from the source and to remove the initial [ from the chunk you're trying to append. It's just a difficult approach.
What you actually want to do is:
read the entire JSON file
parse the JSON into a JavaScript object (or create an empty object if the file didn't exist)
Modify the JavaScript object as necessary (e.g. push into the array to add another element)
stringify the JavaScript object into new JSON
overwrite the entire file with the new JSON.
/* In Node.js:
const fs = require('fs');
try {
initialJSON = fs.readFileSync('example.json');
} catch (ignore) {
initialJSON = '[]';
}
*/
/* Mocked for this example: */
initialJSON = '["one","two"]';
// Common
obj = JSON.parse(initialJSON);
obj.push("three");
finalJSON = JSON.stringify(obj);
/* In Node.js:
fs.writeFileSync('example.json', finalJSON);
*/
/* Mocked for this example: */
console.log(finalJSON);

How to get a particular data from JSON string coming from API in ANGULAR 8 and store in Variable [duplicate]

This question already has answers here:
Safely turning a JSON string into an object
(28 answers)
Closed 2 years ago.
Good day Developers in the house. I need help. I have a json string that i have gotten from API in Angular and console log to see it. I want to get a particular data from the json file and store in a variable because i need to query the data again. Below is how my Json data look like.
{
"done": true,
"record_id": "5fc0a7ac88d2f8534f8e59d8",
"customer_id": "5fa1541f6bd09b290f736608",
"balance": {
"clientId": "qh8RKp9BGhmKCn8ZAAED",
"status": true,
"balance_callback": "https://webhook.site/92b09e29-f08e-4472-b7e8-5875155360d67",
"data": {
"formatted": [
{
"available_balance": 31500,
"ledger_balance": 32000,
"ref": "saving-account",
"status": "active",
"account": "5fa9e536f6b7bb837cb22byu",
"connected": true
},
{
"available_balance": 11200,
"ledger_balance": 11200,
"ref": "current-account",
"status": "active",
"account": "5fa9e535f6b7bb837cb22buy",
"connected": false
},
{
"available_balance": 2000,
"ledger_balance": 2000,
"ref": "current-account",
"status": "active",
"account": "5fa9e536f6b7bb837cb22bty",
"connected": false
}
]
}
},
"Post": {
"callback_url": "https://webhook.site/92b09e29-f08e-4472-b7e8-5875155360d67"
},
"guarantors": [],
"redirect_url": "",
"launchAgain": true,
"hideExit": "",
"options": {},
"directors": null,
"auth": {
"clientId": "qh8RKp9BGhmKCn8ZAythj",
"status": true,
}
I want to get the callback-url under Post in the json file above.. Please any idea on how to do that with any javascript Method.
Let's say you call the date like that
fetch('urlOfTheApi')
.then( response => resonse.json()
.then( json => {
console.log(json);
});
So the solution is
fetch('urlOfTheApi')
.then( response => resonse.json()
.then( json => {
let callback_url = json.POST.callback;
return fetch(callback_url, {method:'POST'}).
})
.then( () => console.log('ok')
.catch( console.error );
Based on your JSON you should create an interface to define the object of the JSON and the particular part of the JSON that you need if you just need that property you could create the following interface
interface Response {
Post: {
callback_url: string;
}
}
In the service where you are requesting the endpoint from your API, you set that this method returns a Response type of data.
And inside of the subscription on your method you could access the property of the object of the JSON.

Javascript parse JSON error, but works fine in validator

When I try to parse this JSON (Discord webhook):
{
"content": "this `supports` __a__ **subset** *of* ~~markdown~~ 😃 ```js\nfunction foo(bar) {\n console.log(bar);\n}\n\nfoo(1);```",
"embed": {
"title": "title ~~(did you know you can have markdown here too?)~~",
"description": "this supports [named links](https://discordapp.com) on top of the previously shown subset of markdown. ```\nyes, even code blocks```",
"url": "https://discordapp.com",
"color": 16324973,
"timestamp": "2018-12-18T09:22:12.841Z",
"footer": {
"icon_url": "https://cdn.discordapp.com/embed/avatars/0.png",
"text": "footer text"
},
"thumbnail": {
"url": "https://cdn.discordapp.com/embed/avatars/0.png"
},
"image": {
"url": "https://cdn.discordapp.com/embed/avatars/0.png"
},
"author": {
"name": "author name",
"url": "https://discordapp.com",
"icon_url": "https://cdn.discordapp.com/embed/avatars/0.png"
},
"fields": [
{
"name": "🤔",
"value": "some of these properties have certain limits..."
},
{
"name": "😱",
"value": "try exceeding some of them!"
},
{
"name": "🙄",
"value": "an informative error should show up, and this view will remain as-is until all issues are fixed"
},
{
"name": "<:thonkang:219069250692841473>",
"value": "these last two",
"inline": true
},
{
"name": "<:thonkang:219069250692841473>",
"value": "are inline fields",
"inline": true
}
]
}
}
Using this code:
var parsed = JSON.parse(req.body)
I get this error:
SyntaxError: Unexpected token o in JSON at position 1
But if I use a website such as
https://jsonformatter.curiousconcept.com
To validate the JSON, it says the JSON is valid.
What is wrong here?
UPDATE
I'm using an express server to simulate discord server, so it sends web hooks to the express server instead, I get the JSON using req.body.
This happens because JSON is a global object (it's the same object where you read the method parse!), so when you invoke JSON.parse(JSON) javascript thinks you want to parse it.
The same thing doesn't happen when you pass the variable to the validator, because it will be assigned to a local variable:
let JSON = "{}";
validate(JSON);
function(x) {
JSON.parse(x); // here JSON is again your global object!
}
EDIT
According to your updated question, maybe it happens because you already use bodyParser.json() as middleware, and when you use it, req.body is already an object and you don't need to parse it again.
Trying to parsing an already parsed object will throw an error.
It would be something like without using JSONStream:
http.request(options, function(res) {
var buffers = []
res
.on('data', function(chunk) {
buffers.push(chunk)
})
.on('end', function() {
JSON.parse(Buffer.concat(buffers).toString())
})
})
For using it with JSONStream, it would be something like:
http.request(options, function(res) {
var stream = JSONStream.parse('*')
res.pipe(stream)
stream.on('data', console.log.bind(console, 'an item'))
})
(OR)
Here is the Some Steps for this issue..
You Can use lodash for resolving this.
import the lodash and call unescape().
const _ = require('lodash');
let htmlDecoder = function(encodedStr){
return _.unescape(encodedStr);
}
htmlDecoder(JSON);

How do I access values in a d3 json file with nested array objects

Previously I was using a json file with the following format:
[{"lat":43.788458853157117,"lng":-79.282781549043008,"category":"volunteer","name":"Rita","url":"", "description":"xxx is a member of 13"},{"lat":43.7,"lng":-79.4,"category":"organization","name":"TCAN","url":"http://tcan.ca","description":"Lorem ipsum"}]
Now I am attempting to generate the json file from a Drupal site and am getting the following structure. How can I reference the lowest level fields. I have looked at examples using d3.net but have not found any that apply.
{
"organizations": [
{
"member": {
"field_category": "organization",
"body": "A network of organizations in Toronto devoted to climate change mitigation and adaptation.",
"URL": "xxx.ca",
"title": "Toronto Climate Action Network",
"field_lat": 43.7,
"field_long": -79.4
}
},
{
"member": {
"field_category": "abc",
"body": "xxx.",
"URL": "",
"title": "yyy",
"field_lat": 43.7,
"field_long": -79.28
}
}
]
}
Assuming that your data is stored in the variable data:
var bottom = data.organizations.map(function(d) { return d.member; });

Fetch JSON data from a file

I got a very simple txt file in JSON format:
{
"menu": "File1",
"bday": [
{
"name": "teo",
"date":"22"
},
{
"name": "john",
"date": "9"
},
{
"name": "maria",
"date": "15"
}
]
}
All I want is to just fetch the data and print them. Like:
teo : 22
john:9
...etc...
I don't care about this. I just want to fetch the data.
Your answer is plainly XMLHttpRequest, which is multi-browser compatible JavaScript without need for a library. You can always create your own library for some backward-compatibility.
Put the JSON in a file on your server (for example, data.js) and then use jQuery to fetch the file. Something like this:
var json;
$.getJSON("data.js", function(data){
json = data;
});

Categories

Resources