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'));
Related
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
New react developer here, here i have two API's, first one gives an object :
{ id: "98s7faf", isAdmin: true, name: "james"}
second one gives an array of objects :
[
{ billingName: "trump", driverName: "james" },
{ billingName: "putin", driverName: "alex" },
{ billingName: "kalle", driverName: "james" },
{ billingName: "sussu", driverName: "trump" },
{ billingName: "vladimir", driverName: "james" },
]
my question is, when user goes to the page, the page should automatically check both API'S, from first api name and from second api driverName, and if those two have same value then take that specific object from an array and pass it to these:
setOrders(res);
setRenderedData(res);
so at the moment there are three objects (those which have value of james) inside an array which matches name from first api, so it should pass those, and the rest which have different value it should not let them pass. here is my code, what have i done wrong ? instead of some(({ driverName }) i need some kind of filter ?
useEffect(() => {
api.userApi.apiUserGet().then((res1?: User ) => {
return api.caApi.apiCaGet(request).then((res?: CaDto[])
=> {
if (res.some(({ driverName }) => driverName === res1?.name)) {
setOrders(res);
setRenderedData(res);
console.log(res);
}
});
});
}, [api.caApi, api.userApi]);
you need to filter your response to extract the right objects given your condition.
useEffect(() => {
api.userApi.apiUserGet().then((res1?: User ) => {
return api.caApi.apiCaGet(request).then((res?: CaDto[])
=> {
const filteredData = res?.filter(({ driverName }) => driverName === res1?.name);
if(filteredData?.length) {
setOrders(filteredData);
setRenderedData(filteredData);
console.log(filteredData);
}
});
});
}, [api.caApi, api.userApi]);
note: having 2 states that holds the same values (orders, renderedData) is not a good practice, you might consider to refactor your logic.
I'm new in Vue js, and I have data in array object like below when I use vue-multiselect.
[
{
"id": 1,
"add_on_type": "Xtra",
"name": "test",
"price": 12,
"created_at": "2020-06-25 10:12:43",
"updated_at": "2020-06-25 10:12:43"
},
{
"id": 3,
"add_on_type": "Xtra",
"name": "Some x",
"price": 120,
"created_at": "2020-06-30 05:47:52",
"updated_at": "2020-06-30 05:47:52"
}
]
but in my function I need to access like key:value like below
"xtra": {
// key: value
0: 1
1: 3
}
but I get all array object instead of id only. I need to get the ID only in array, below is my code. I don't know how to get only id from array using below code.
this.$axios
.get("items/" + this.item)
.then(res => {
// below line is how I get the array object, but I need only id in array.
data.xtra = this.extra;
console.log(data);
})
.catch(err => {
throw err;
});
this maybe easy for some people, but I cannot find the way to to do. any help would be appreciated. thanks in advance
If I understood correctly your question, this.item is holding an object retrieved from the array. If is like this, it should be as easy as:
.get("items/" + this.item.id)
if you want to create new array you can do this at your return from axios
.then(res => {
let arr = res.data
this.xtra = arr.map(x =>
x.item.id)
})
First declare Items as reactive array in setup function
const tools = reactive([]);
Then in methods, retrieve
axios.get("/user-items").then(response => {
var items = [];
response.data.forEach((item, index) => {
items.push(item.id);
})
Object.assign(this.items, items);
});
I just want to make sure there is no such thing... because I cannot find anything mentioning this:
Currently, when I use json_encode($array), I get a json object that look like this:
{
"1": {"user_id":1,"test":"","user_name":"potato0","isok":"true"},
"2":{"user_id":2,"test":"","user_name":"potato1","isok":" true"},
"3":{"user_id":3,"test":"","user_name":"potato2","isok":" true"},
"4":{"user_id":4,"test":"","user_name":"potato3","isok":"locationd"}
}
and I would like to run the .filter()/.forEach() methods.
but they wont run on objects ({...}) and will run on arrays ([...]).
Edit: It seems that it's not sure what I am getting so this is a real var_dump and json_encode() example:
var_dump($array);
array (size=2)
'status' => boolean true
'data' =>
array (size=3)
'fruits' =>
array (size=9)
'fruit_id' => int 246
'fruit_name' => string 'banana' (length=15)
'vegtables' =>
array (size=9)
'veg_id' => int 253
'fruit_name' => string 'potato' (length=20)
echo json_encode(['status' => true, 'data' => $fruits]);
{
"status":true,
"data":{
"fruits":{
"fruit_id":246,
"fruit_name":"banana"
},
"vegtables":{
"veg_id":253,
"veg_name":"potato"
}
}
}
the json returned is defined as an "Object" (checked using typeof)
** I'm not willing to turn my object to an array on the js side, I aware about this "trick" and I prefer to fetch a json array from php as an array, please focus on my question **
You need to change the main object to an Array. I think below code is what you're looking for.
Your Input :
var data = {
"1": {"user_id":1,"test":"","user_name":"potato0","isok":"true"},
"2":{"user_id":2,"test":"","user_name":"potato1","isok":" true"},
"3":{"user_id":3,"test":"","user_name":"potato2","isok":" true"},
"4":{"user_id":4,"test":"","user_name":"potato3","isok":"locationd"}
};
Convert Object to Array
var result = Object.keys(data).map(function(key) {
return data[key];
});
Now you can use Filter for the converted array
var filtered = result.filter(row => { return row.user_id > 1; });
And Filtered Result is:
[{
"user_id": 2,
"test": "",
"user_name": "potato1",
"isok": " true"
},{
"user_id": 3,
"test": "",
"user_name": "potato2",
"isok": " true"
},{
"user_id": 4,
"test": "",
"user_name": "potato3",
"isok": "locationd"
}]
Hope this is what you're looking for and here is working demo link : https://playcode.io/282703?tabs=console&script.js&output
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.