how to change this string to an array of objects [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 20 days ago.
Improve this question
SOLVED!:
The api had weird characters copied that were being sent over and breaking my javascript. always double check the values you are being sent!
To give full context on this:
to give the full context, i have a post api that is giving me the above structure in postman. i need to check the number and the code and if there are multiple objects returned. when i try to simply return the json i get the following error :json.parse()SyntaxError: Expected property name or '}' in JSON at position 2. Ive been trying to create work arounds to get the value but the best i can do is get it returned as a string using the code above. My goal is to check the code and the number of each object so i can validate against it. thank you for your help!
when returning my data from a post API I'm getting the response as a string. It's a formatted like an array of objects but I'm having difficulty parsing it due to the structure. the structure is as follows:
{
"items": [
{
"number": 119777777,
"code": "S",
"name": "name Full award ",
"year": 2021,
"updatedate": "04-JAN-2023"
},
{
"number": 119777777,
"code": "H",
"name": "Hospital funding.",
"year": 2021,
"updatedate": "04-JAN-2023"
}
]
}
how can I transform this into something usable? I need to check the values of the code in each object for validation.
heres my code:
function GetFunding() {
var responseClone; // 1
fetch('my url',{
method: "POST"
})
.then(function (response) {
responseClone = response.clone(); // 2
return response.json();
})
.then(function (data) {
// Do something with data
}, function (rejectionReason) { // 3
console.log('Error parsing JSON from response:', rejectionReason, responseClone); // 4
responseClone.text() // 5
.then(function (bodyText) {
console.log('Received the following instead of valid JSON:', bodyText); // 6
});
});
};

let fetchRes = fetch(
"https://jsonplaceholder.typicode.com/todos/1")
fetchRes.then(res =>
res.json()).then(data => {
console.log(data)
})
Your response is also correct but you can simplify using my code and for error handle you can write catch block.
You are saying that you are getting response in string but you should know that a object always have keys as a string , Even if you pass a number as a key to object , It will always go to string to object.

I think something like this could work out:
function GetFunding() {
fetch('my url',{
method: "POST"
})
.then(response => response.json())
.then(data => {
const items = data.items;
items.forEach(item => {
if (item.code === 'S') {
// do something
} else if (item.code === 'H') {
// do something else
}
});
})
.catch(error => console.error(error));
};

const string = '{ "items": [ { "number": 119777777, "code": "S", "name": "name Full award ", "year": 2021, "updatedate": "04-JAN-2023" }, { "number": 119777777, "code": "H", "name": "Hospital funding.", "year": 2021, "updatedate": "04-JAN-2023" } ] }';
const obj = JSON.parse(string);
const arrayOfObjects = obj.items;

Related

Unable to get length of JSON data in JS

I have a JSON file with some items. I'd like to randomly select one to display using Javascript. Here's the JSON file:
{
"keywords": [
{
"name": "item1",
"property1": "value1",
"property2": "value2",
"property3": "value3"
},
{
"name": "item2",
"property1": "value4",
"property2": "value5",
"property3": "value6"
}
]
}
I fetch the file as follows:
let data;
function fetchJSON() {
fetch('../keyworddata.json')
.then(response => {
if(!response.ok) throw new Error("HTTP status " + response.status);
return response.json();
})
.then(jsonData => {
data = jsonData;
})
.catch(error => {
console.error('Error:', error);
});
}
fetchJSON();
myData = JSON.parse(data);
lengthOfMyData = Object.keys(myData.keywords[0]).length;
console.log(lengthOfMyData);
However, I get the following error:
JSON Parse error: Unexpected identifier "object"
Can you help me? I'd like to find the number of items in the JSON file and then pick a random item from the list.
There's some weirdness going on here: you're using a global variable for data associated with a function, your second then is wrong in terms of what you named things (response.json() parses JSON, it does not return JSON. It returns a normal JS datastructure, leading to the next bit) and you're trying to parse regular JS data as if it's JSON.
So let's fix all of that:
function fetchJSON(filename) {
return fetch(filename)
.then(response => response.json())
.catch(error => {
// Log error, and return an object that the consuming
// code can still work with, but is effectively "empty"
console.error({error});
return { keywords: [] };
});
}
const { keywords } = await fetchJSON(`../keywords.json`);
console.log(keywords.length);
Although it would make far more sense to not make fetchJSON handle the errors, and instead have the calling code have a try/catch so that if the fetch fails for whatever reason, your calling code knows where to branch next.

Filter object by name with JavaScript

I made a request to an endpoint and I get this object, I'm filtering the name like this:
fetch('http://endpoint', requestOptions)
.then((response) => response.json())
.then((result) => {
const onlineUsers = result.resource.items[1].onlineUsers >= 1;
console.log(onlineUsers);
})
.catch((error) => console.log('error', error));
This workers, but I just need the result of what is in the key named Forms, but there is a possibility that it will change its position, so the items[1] it may not work anymore
This is an example of the object I receive:
{
"type": "application/vn+json",
"resource": {
"total": 4,
"itemType": "application",
"items": [
{
"name": "Test",
"onlineUsers": 1
},
{
"name": "Forms",
"onlineUsers": 1
},
{
"name": "Users",
"onlineUsers": 7
},
{
"name": "OnlineUsers",
"onlineUsers": 5
}
]
},
"method": "get",
"status": "success"
}
Is there any way to receive this object and filter by name? Like:
if (hasName === "Forms", get onlineUsers) {
// Do something
}
Thanks!
As suggested in your question, you can use filter on your array. Something like that:
console.log(
result.resource.items.filter((item) => item.name === "Forms")
);
This will print an array with all items having the name Forms. Using your example:
[
{
"name": "Forms",
"onlineUsers": 1
}
]
If there is only one item with the name Forms, or if you want only the first one, find may be a good alternative with a similar syntax:
console.log(
result.resource.items.find((item) => item.name === "Forms")
);
This will only print the first found object (or null if none is matching), without the array "pollution":
{
"name": "Forms",
"onlineUsers": 1
}
result.resource.items.filter((item) => item.name === "Forms")
Will filter your objects for you
Note, you will get back an array of all the filtered objects meeting the condition.
If you know there's only one object that matches that name you can use find which will return the first match so you don't necessarily need to iterate over the entire array.
Here's a little general function that might help. Pass in the data, the value of name, and the property you want the value of. If there is no match it returns 'No data'.
const data={type:"application/vn+json",resource:{total:4,itemType:"application",items:[{name:"Test",onlineUsers:1},{name:"Forms",onlineUsers:1},{name:"Users",onlineUsers:7},{name:"OnlineUsers",onlineUsers:5}]},method:"get",status:"success"};
function finder(data, name, prop) {
return data.resource.items.find(item => {
return item.name === name;
})?.[prop] || 'No data';
}
console.log(finder(data, 'Forms', 'onlineUsers'));
console.log(finder(data, 'morf', 'onlineUsers'));
console.log(finder(data, 'Users', 'onlineUsers'));
console.log(finder(data, 'Users', 'onlineUser'));

Retrieve multidimensional JSON data where index number is randomized/unknown

Been delivered some confusing JSON data with a problem I haven't seen before.
The JSON is formatted similar to this structure:
[
{
"title": "Event",
"start_date": "2022-08-20 15:00:00",
"end_date": "2022-08-20 16:00:00",
"branch": {
"85": "branchname"
},
"room": {
"156": "roomname"
},
"age_group": {
"5": "Youth",
"6": "Teen"
}
},
{
"title": "Event02",
"start_date": "2022-08-20 15:00:00",
"end_date": "2022-08-20 16:00:00",
"branch": {
"72": "branchname"
},
"room": {
"104": "roomname02"
},
"age_group": {
"5": "Youth",
"6": "Teen"
}
}
]
I'm trying to pull roomname out of the data, but it's nested in an object that has a random index number. If I manually put in the index number, I can retrieve the data, but the number changes every entry.
If I can figure out how to retrieve the number and store it in a variable, then use it again, or just somehow wildcard to just show any child of any key under the parent node "room" it would work perfect, but I don't know of a way to do this in javascript.
I'm limited to vanilla javascript, no external libraries or jquery.
here is the code that will output correctly if I manually enter the index numbers, but it only works for a single entry.
<script>
const url = 'example.json';
fetch(url)
.then((response) => {
return response.json();
})
.then((json) => {
json.map(function(event) {
console.log(`${event.start_date}`);
console.log(`${event.title}`);
console.log(`${event.room[156]}`);
return element;
});
}, 80);
</script>
EDIT: Forgot to point out, there is always only 1 entry in the "room" tag, but it's index is randomized, so if you just select the room tag it returns undefined or invalid. If I could wildcard the index so it just tries them all, or somehow retrieve the index number and store it in a variable, it would fix the issue.
I think this will work:
Here as you don't know the key so, instead of just guessing, you can use Object.values(JSONObjName) to get the list/array of values in that json.
Here I'm also using optional chaining (?.) to handle the case when the json has no key value pairs.
<script>
const url = 'example.json';
fetch(url)
.then((response) => {
return response.json();
})
.then((json) => {
json.map(function(event) {
const roomName = Object.values(event.room)?.[0];
console.log(`${event.start_date}`);
console.log(`${event.title}`);
console.log(`${roomName}`);
return {...event, room: roomName};
});
}, 80);
</script>
As long as you always want the first key you can fetch it like this
room = event.room[Object.keys(event.room)[0]]
if you want to get just roomname, you could do Object.values(room)[0]
or if you want the index and value you could go for Object.entries(room)[0]
arr?.map(({ room }) => {
for(let [key, value] of Object.entries(room)) {
console.log('Random Key : ',key)
console.log('Roomname : ', value)
console.log('Using random key : ',room[key])
}
})
By this way you can find the value of room against the random key.
Or you can try this if it is more relevant to you.
arr.map(({ room }) => {
for(let key of Object.keys(room)) {
console.log('Random Key : ',key)
console.log('Using random key : ',room[key])
}
})
Since you may want to do this for branch as well, here's an alternative solution which uses the object key as a computed property name (aka "dynamic key") to get the value.
And since, in this example it's done more than once, I've added that to a function that you can call in the destructuring assignment.
const data=[{title:"Event",start_date:"2022-08-20 15:00:00",end_date:"2022-08-20 16:00:00",branch:{85:"branchname"},room:{156:"roomname"},age_group:{5:"Youth",6:"Teen"}},{title:"Event02",start_date:"2022-08-20 15:00:00",end_date:"2022-08-20 16:00:00",branch:{72:"branchname02"},room:{104:"roomname02"},age_group:{5:"Youth",6:"Teen"}}];
// Get first key from an object
function getKey(obj) {
return Object.keys(obj)[0];
}
const out = data.map(obj => {
// Destructure the object and call `getKey` with the
// object to get its only key, and use that
// as a computed property to get its value, which
// we then relabel e.g. `roomName`
const {
branch: { [getKey(obj.branch)]: branchName },
room: { [getKey(obj.room)]: roomName },
...rest
} = obj;
// Now just return a new object with your new keys/values
return { ...rest, branchName, roomName };
});
console.log(out);
Additional documentation
Rest parameters
Spread syntax

JSON Parse nested objects in React

I'm fetching data in React from a MySQL database. MySQL auto-escapes my values including nested objects. I'm using the .json() function on the top-level but i'm not able to use this on sub-levels, nor JSON.parse(response[0].data) will work.
What is the right way of doing this?
fetch(`http://localhost:3000/getQuiz${window.location.pathname}`, requestOptions)
.then(response => response.json())
.then(response => {
console.log(response)
// {
// "id": 1,
// "url": "asd2q13",
// "data": "{name: \"Marie\", answers:[\"1\", \"3\", \"0\"]}"
// }
console.log(typeof response)
// object
console.log(response[0].data)
// {name: "Marie", answers:["1", "3", "0"]}
console.log(typeof response[0].data)
// string
console.log(response[0].data.name)
// undefined
})
The response.data is not a valid JSON string. You can try:
const response = {
"id": 1,
"url": "asd2q13",
"data": "{name: \"Marie\", answers:[\"1\", \"3\", \"0\"]}"
}
console.log(eval('(' + response.data + ')'))
Or Better:
const response = {
"id": 1,
"url": "asd2q13",
"data": "{name: \"Marie\", answers:[\"1\", \"3\", \"0\"]}"
}
function looseJsonParse(obj) {
return Function('"use strict";return (' + obj + ')')();
}
console.log(looseJsonParse(response.data))
But,
Warning: Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use eval(). See Never use eval()!, below.
I suggest you serialize the data correctly on the backend. I think the MySQL database driver can do this. Also, see Parsing JSON (converting strings to JavaScript objects)
MySQL (MySQL2) for Node was the big problem here. It's suppose to serialize "automatically", but somehow it ends up all wrong.
If I do JSON.Stringify() explicitly for the nested part before storeing it in the database it works!
const sendToDatabase = () => {
let nested = JSON.stringify({ name: "Marie", answers: ["2", "1", "0"] })
let post = { url: "asd2q13", data: nested}
var query = connection.query(
"INSERT INTO users SET ? ", post,
function (error, results, fields) {
if (error) throw error;
}
);
console.log(query.sql);
};
Then I call this on the front end
console.log(JSON.parse(response[0].data).name)
// Marie (string)
console.log(JSON.parse(response[0].data).answers)
// ["2", "1", "0"] (array)
The raw output from this is
{"name":"Marie","answers":["2","1","0"]}
insted of
{name: \"Marie\", answers:[\"1\", \"3\", \"0\"]}

How do I find a JSON value with a specific ID?

I have an object and I’m trying to find a specific value using an ID in ECMAScript6.
I’ve tried something like this: myvalue = this.json.find(x => x == '1234');
The JSON looks something like this:
{
"results": [
{
"abcde1234": {
"value": 4
}
},
{
"zxcv4567": {
"value": 2
}
}
]
}
All the examples I’ve found can only find off named key-value pairs.
Try
json.results.find(x => /1234/.test(Object.keys(x)[0]));
json = {
"results": [
{
"abcde1234": {
"value": 4
}
},
{
"zxcv4567": {
"value": 2
}
}
]
}
let r = json.results.find(x => /1234/.test(Object.keys(x)[0]));
console.log(r);
const json = {
'1234': { 'value' : 4},
'5678': { 'value' : 10}
};
const value = json['1234'];
console.log(value);
The JSON data doesn't seem proper.
But in case you are finding by key, you can directly access this, something like:
Parsed JSON maps directly to JavaScript types: Object, Array, boolean, string, number, null. Your example used find() which is (normally) a method used with arrays. If your JSON was structured like this, you could expect to use find:
const jsonString = '["a", "b", "c"]';
const jsonData = JSON.parse(jsonString);
jsonData.find(x => x === "a"); // "a"
But it seems like your data is structured as an object, so you can use normal property access:
const jsonString = '{"1234": {"value": 4}, "5678": {"value": 10}}';
const jsonData = JSON.parse(jsonString);
jsonData["1234"] // {value: 4}
jsonData["1234"].value // 4
EDIT
OP changed the data example, so the above code is less directly applicable, but the general point is: once you parse it, it's just javascript.

Categories