How to access nested array inside a JSON object from javascript - javascript

I am working with a json object that has nested arrays as well as names with spaces such as Account ID. I need to display just the Account ID's in my Vue.js application. I am able to get my entire response.data json object but not too sure how to get just the Account ID when it's nested like the example below.
JSON
"response": {
"result": {
"Accounts": {
"row": [
{
"no": "1",
"FL": [
{
"val": "ACCOUNT ID",
"content": "123456789"
},
...
Vue.js
<script>
import axios from "axios";
export default {
name: 'HelloWorld',
data () {
return {
accounts: [],
accountIDs: []
}
},
mounted() {
var self = this;
axios.get('https://MYAPIGETREQUEST')
.then( function(res){
self.accounts = res.data;
self.accountIDs = //This is where I want to get the Account ID
console.log('Data: ', res.data);
})
.catch( function(error){
console.log('Error: ', error);
})
}
}
</script>

Try something like this
if(res.data.response.result.Accounts.row[0].FL[0].val === 'ACCOUNT ID') {
self.accountIDs = res.data.response.result.Accounts.row[0].FL[0].content;
...
}

You can also try something like this:
let rowAccounts = response.result.Accounts.row
.map(row => row.FL
.filter(FL => FL.val === 'ACCOUNT ID')
.map(acc => acc.content)
);
self.accountIDs = [].concat.apply([], rowAccounts);
In rowAccounts, you get and array of accounts array per row like:
[
0: ['acc row 1', 'another acc row1'],
1: ['acc row 2'....]
]
Now it all depends upon your implementation the way you like it.

Related

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'));

How to loop through objects and count unique values of key?

I have logs of json files which are objects that look like
{
"logs": [
{
"id": "12321321321321",
"email": "test#email.com",
"message": "ahahaha"
},
{
"id": "12321321312",
"email": "test#email.com",
"message": "hahahaha."
},
"id": "12321321321"
}
I need to return a new object that contains
{
"hello_id": outer id of the json file,
"array": [
{
"email": "test#me.com",
"total": 2
}
]
}
So far I am looping through the json files and have
jsonsInDirectory.forEach((file) => {
const fileData = fs.readFileSync(path.join("./logs", file), "utf8");
const jsonData = JSON.parse(fileData);
}
});
The key is "logs" and "id" and the values are the objects in the "logs" and the value of "id"
How can I count and return a new object at the same time?
You can try this approach: make a hash object that counts emails. Then just map it to an array of objects.
const data = {
logs: [{
id: "89004ef9-e825-4547-a83a-c9e9429e8f95",
email: "noah.sanchez#me.com",
message: "successfully handled skipped operation."
},
{
id: "89004ef9-e825-4547-a83a-c9e9429e8f95",
email: "noah.sanchez#me.com",
message: "successfully handled skipped operation."
},
{
id: "89004ef9-e825-4547-a83a-c9e9429e8f95",
email: "noname#me.com",
message: "successfully handled skipped operation."
}],
id: "56f83bed-3705-4115-9067-73930cbecbc0",
};
const emails = data.logs.reduce((acc, { email }) => {
acc[email] = (acc[email] ?? 0) + 1;
return acc;
}, {});
const tally = Object.entries(emails)
.map(([email, total]) => ({ email, total }));
const result = { logs_id: data.id, tally };
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0 }
When you do const jsonData = JSON.parse(fileData);, you get the file data as a JSON and knowing the struct of that JSON you can easily get the info.
I have created a example https://codesandbox.io/s/stackoverflow-logs-count-example-jys2vg?file=/src/index.js
It may not solve exactly wath you want.
To solve this problem with the most time efficiency, you can create a tally object by firstly creating a map of the occurences of each mail with the email as the key and no of occurences as the value, since this will take constant (O(1)) time to execute, afterwhich you can create the tally array from the map as given below
output = []
jsonsInDirectory.forEach((file) => {
const fileData = fs.readFileSync(path.join("./logs", file), "utf8");
const jsonData = JSON.parse(fileData);
var map = {}
jsonData.logs.forEach((log) => {
if(log.email in map){
map[log.email] += 1
}
else {
map[log.email] = 1
}
});
var tally = []
for(var email in map){
tally.push({email: email, total: map[email]})
}
output.push({logs_id: jsonData['id'], tally: tally});
})

Javascript Array of object value into multidimensional array

I am in process of learning expressJS with NodeJS.
I am trying to insert multiple rows into mySQL table. Since the bulk insert query requires data like
[["a",1], ["b",2], ["c",3]]
How can I transform my array of objects to such form? Here is my JSON post data
[
{
"productID" : 1,
"stock": -3
},
{
"productID" : 1,
"stock": 5
}
]
How to tranform such JSON object into the multidimensional array?
[[1,-3],[1,5]]
Here is what I have tried so far.
let promises = []
req.body.map((n) => {
promises.push(new Promise(resolve => {
let { productID, stock } = n
let values = {
PRODUCT_ID: productID,
STOCK: stock
}
let sql = 'INSERT INTO product_stock_history SET ?'
db.connection.query(sql, values, (err, results) => {
if (err) {
console.log("Failed to add stocks record: " + err)
res.sendStatus(500)
return
} else {
res.send("Stock record has been added")
}
})
}))
})
The above code is working, but in the end I have error with the mySQL syntax which I believe something to do with the promise. I am not familiar with the promise :)
Error: Can't set headers after they are sent.
So what i want to achieve is just the mapping without Promise.
thanks
You could pass Object.values as parameter to map like this:
const input = [
{
"productID" : 1,
"stock": -3
},
{
"productID" : 1,
"stock": 5
}
]
const output = input.map(Object.values)
console.log(output)

How does axios get the tree json and render a vue page?

Recently, due to the needs of the vue background management project, the page needs to make an infinite tree.I have return json data of http://private-4f7c1-zyl1.apiary-mock.com/questions. Go to the enter link description here.
Return is like this:
[
{
"id":1,
"name":"HuaWei",
"pid":0
},
{
"id":2,
"name":"Apple",
"pid":0
},
{
"id":3,
"name":"Iphone X",
"pid":2
},
{
"id":4,
"name":"nove 3",
"pid":1
},
{
"id":5,
"name":"Iphone 8 plus",
"pid":2
}
]
I have Vue code:
new Vue({
el: "#app",
data: {
phoneList: []
},
mounted() {
axios.get('https://private-4f7c1-zyl1.apiary-mock.com/questions')
.then(response=> {
console.log(response);
this.phoneList = response.data;
})
.catch(error => {
console.log(error);
});
},
methods: {
}
})
I can provide an effect HTML template like this:enter link description here.
I want this effect:
This is a data structure problem. You could reshape the Axios response into a data structure that facilitates rendering that particular tree:
In a computed property (e.g., named "phoneGroups"), get all the groups, indicated by pid of 0:
const groups = this.phoneList.filter(x => x.pid === 0);
For each group, get the items belonging to that group, indicated by a pid that matches the group ID:
const data = {};
for (const g of groups) {
const subitems = this.phoneList.filter(x => x.pid === g.id);
data[g.id] = {
group: g,
subitems,
};
}
return data;
In the template, render the computed result as follows:
<ul>
<li v-for="({group, subitems}) in phoneGroups" :key="group.id">
<span>{{group.name}}</span>
<ol>
<li v-for="subitem in subitems">-- {{subitem.name}}</li>
</ol>
</li>
</ul>
demo

Unable to delete _id field from object after create using feathersjs

i want to modify my hook.data object in my node application after insertion of data. actually i'm not able to.
create: [function(hook, next) {
delete hook.data._id;
hook.data = { problem: hook.data }
postJson(hook.app.get('jsprintUrl'), hook.data)
.then(data =>{
hook.result = data;
next()
})
}]
result: still _id is exist
{
"_id": "59ca334e7bc4e06b140aadf9",
"algorithm": [
{
"name": "SA"
}
]
}
i update object using the hook.result in following way and hook.result will have its Mongoose documents converted to plain objects. more information reference link
create: [function(hook, next) {
delete hook.result._id;
hook.result = { problem: hook.result }
postJson(hook.app.get('jsprintUrl'), hook.result)
.then(data =>{
hook.result = data;
next()
})
}]
result: It was removed from response
{
"algorithm": [
{
"name": "SA"
}
]
}

Categories