Using Axios to parse JSON objects containing only values without keys - json

I am trying to parse this json into two separate arrays
{"2022-08-11":11561.71,"2022-08-12":11396.5433,"2022-08-13":10875.3483,"2022-08-14":10036.1867,"2022-08-15":10307.895,"2022-08-16":10358.7683,"2022-08-17":10220.6033,"2022-08-18":10321.7317,"2022-08-19":10924.965,"2022-08-20":10776.9083,"2022-08-21":10133.3483}
currently I managed to get the object using axios on Vue, however I am struggling to seperate the strings of dates from the integer values in the arrDate and arrValue empty arrays
data: () => ({
arrDate: [],
arrValue: [],
totalVuePackages: null
}),
created(){
axios.get("https://api.coindesk.com/v1/bpi/historical/close.json?start=2019-01-01&end=2019-12-31").then(
response => this.totalVuePackages = response.data);
}
}

You can simply use Object functions :
this.arrDate = Object.keys(response.data)
this.arrValue = Object.values(response.data)

If you want to put the keys in one array and the values in another, use the following
// your Axios response
const response = {data:{"2022-08-11":11561.71,"2022-08-12":11396.5433,"2022-08-13":10875.3483,"2022-08-14":10036.1867,"2022-08-15":10307.895,"2022-08-16":10358.7683,"2022-08-17":10220.6033,"2022-08-18":10321.7317,"2022-08-19":10924.965,"2022-08-20":10776.9083,"2022-08-21":10133.3483}};
// Reduce the entries (key / value pairs) into two separate arrays
const [dates, numbers] = Object.entries(response.data).reduce(
([keys, values], [key, value]) => [
[...keys, key],
[...values, value],
],
[[], []]
);
console.log("dates", dates);
console.log("numbers", numbers);
// then assign to your Vue data with
// this.arrDate = dates;
// this.arrValue = numbers;
.as-console-wrapper { max-height: 100% !important; }

Related

Sorting values from JSON by values in React

I have a React form that uses i18 next translations from JSON file in a dropdown. The objects are very simple: one key, one translation, like this (but the file is very long, there are dozens of keys).
JSON:
{
"country": "Country",
"big": "Big",
"dog": "Dog",
"integration": "Integration"
}
Code that uses data from JSON:
const createField = (parentName: string, item: any) => {
const field = {
type: `${item.type}`,
name: `${parentName ?? ''}${parentName?.length ? '.' : ''}${item.name}`,
label: t(`${item.label ?? item.name}`),
properties: {
placeholder: `${item.placeholder ?? ''}`
} as any,
};
if (item.type === 'select' ) {
field.properties = {
...field.properties,
options: [].concat(item.options?).sort((a,b) =>
t(`${a.value}`) > t(`${b.value}`) ? 1 : -1).map((option: any) => {
return {
label: t(`${option.label}`),
value: option.value
};
}),
};
};
};
I want the dropdown to be sorted according to the value alphabetically because in each language the order would be different. Everything I tried sorts the array from this JSON according to the key.
I tried concat(item.options?) for sorting but getting errors "Expression expected" and "property doesn't exist".
Also tried this solution, but the dropdowns turned from text into random numbers.
if (item.type === 'select' ) {
field.properties = {
...field.properties,
options: Object.entries(item.options)
.sort(([key1], [key2]) => t(key1).localeCompare(t(key2)))
.map(([label, value]) => ({
label: t(label),
value
}))
};
};
Issue
Assuming that item.options is the JSON data you are trying to sort and convert to a list of options, then the issue is that you've appended the entire options object instead of each individual option. The result is an array of length 1. Another issue is that your data is a dictionary of key-value pairs, not an array of objects with label and value properties.
Solution
You can use both Object.entries and Object.fromEntries to convert the object to an array of key-value pairs and back. For the sorting function you want to sort by the key, and since the keys are strings, use localeCompare for the string comparison.
const data = {
country: "Country",
big: "Big",
dog: "Dog",
integration: "Integration"
};
const sortedData = Object.fromEntries(
Object.entries(data).sort(([key1], [key2]) => key1.localeCompare(key2))
);
console.log(sortedData);
Since you really want an array of shape [{ label: '...', value: '...' }, ...] you can use an array.map to map the array of key-value pairs to an array of objects with the shape you need for mapping in the option values.
const data = {
country: "Country",
big: "Big",
dog: "Dog",
integration: "Integration"
};
const sortedData = Object.entries(data)
.sort(([key1], [key2]) => key1.localeCompare(key2))
.map(([label, value]) => ({
label,
value
}));
console.log(sortedData);
For the actual rendering of your options:
options: Object.entries(item.options)
.sort(([key1], [key2]) => t(key1).localeCompare(t(key2)))
.map(([label, value]) => ({
label: t(label),
value
}))
Since it's not very clear which of the key or value of the JSON data is your option label/value you may needs to tweak the above to fit. I can help here if needed.
Hope it helps:
sort object by key and result is an array of sorted keys
const obj={
"country": "Country",
"big": "Big",
"dog": "Dog",
"integration": "Integration"
}
const sortedKeys=Object.keys(obj).sort();
console.log(sortedKeys);
sort object by value and result is an array of sorted values
const obj={
"country": "Country",
"big": "Big",
"dog": "Dog",
"integration": "Integration"
}
const sortedValues=Object.values(obj).sort();
console.log(sortedValues)
sort object by value and result is an object
const obj={
"country": "Country",
"big": "Big",
"dog": "aDog",
"integration": "Integration"
}
//for case insensitive use this function
const sortedByValue=Object.values(obj).sort(function(a, b) {
return (a.toUpperCase() < b.toUpperCase()) ? -1 : (a.toUpperCase() > b.toUpperCase()) ? 1 : 0;
})
function getKeyByValue(value) {
return Object.keys(obj).find(key => obj[key] === value);
}
const sortedObj={};
sortedByValue.map(value=>{
const key=getKeyByValue(value)
sortedObj[key]=value;
})
console.log(sortedObj)

How to extract JSON value in strangely formatted array?

I'm using a custom script for importing JSON into Google Sheets through a function. I can import values from propertys without any problem, but I have some problem with a specific array. It is a property which contains more information, but it seems the formatting makes the array into one single value instead of several (something with the slashes?). First, the script:
function getStat(url, propertyName)
{
let content = UrlFetchApp.fetch(url).getContentText();
let parsed = JSON.parse(content);
let processed = parsed.data
.filter(e =>
// Conditions go here:
e.season_format === 'Domestic League' &&
e.season === '2020/2021'
)
.map(e => e.stats[propertyName]);
return processed;
}
I want to get the value after "3" in the array called additional_info (simplified version below). But when I try to get the value, instead I get the third character in the array. I don't get "55" which is the value. I've tried with a bunch of variants. But I can't get it to work. For example, additional_info["3"] returns the third character in the array, not the value. Any tips? I've no problem getting the values of suspended_matches and home_AttackAdvantage.
{
"success": true,
"data": [
{
"season": "2020/2021",
"season_format": "Domestic League",
"stats": {
"suspended_matches": 20,
"homeAttackAdvantage": 3,
"additional_info": "{\"1\":1,\"2\":2,\"3\":55,\"4\"}"
}
}
]
}
The issue was that additional_info is yet another JSON string, so you have to parse it again.
function getStat(url, propertyName, additionalProp)
{
let content = UrlFetchApp.fetch(url).getContentText();
let parsed = JSON.parse(content);
let processed = parsed.data
.filter(e =>
// Conditions go here:
e.season_format === 'Domestic League' &&
e.season === '2020/2021'
)
.map(e => additionalProp
? [
e.stats[propertyName],
JSON.parse(e.stats.additional_info)[additionalProp]
]
: e.stats[propertyName]
);
return processed;
}
This gives you a function you can use in a formula:
=getStat(
"https://api.footystats.org/team?key=example&team_id=93",
"suspended_matches",
"330"
)
If you don't specify the third argument, it will just return a single column.

How to Unwrap Json data in angular?

I have a Json data in this format
I want to parse this data in angular typescript when I am calling the rest API. How to do it.
Here this part is my java class object which I want to convert to my model class array.
"gameId": 66,
"kashScore": 0,
"samScore": 1,
"wonBy": "Sam",
"createUserId": 0,
"lastModifiedUserId": 0,
"creationDate": "2020-04-20T14:05:44.263+0000",
"lastModifiedDateTime": "2020-04-20T14:05:44.264+0000",
"sessionId": 1000,
"count": null
My model class
And this information is for tracking pagination.
I tried something like this, but it gives error as:-
Your response is just an array. The data that represents Fifa[] is the first item in the response array.
The HttpClient won't magically convert it for you. If you want to return Fifa[] from your service, then you need to map your response to that type.
return this.http.get<any[]>(fifaUrl).pipe(
map((response: any[]) => response[0])
);
EDIT
You have stated that you want to return all information from the response. In that case you should return an object that implements GetResponse from service function (and probably think about a more suitable name).
fetchAllGamesRecordPaginate(
pageNumber: number, pageSize: number
): Observable<GetResponse> {
const fifaUrl = ${this.baseUrl}/demo/pageNumber/${pageNumber}/pageSize/${pageSize};
return this.httpClient.get(fifaUrl).pipe(
map((response: any[]) => {
const pagination = response[1];
return {
fifa: response[0],
totalRecord: pagination.totalRecord,
pageSize: pagination.pageSize,
pageNumber: pagination.pageNumber,
totalPages: pagination.totalPages
};
})
);
}
Here I am mapping the response array to an object that implements GetResponse.
If you want the method to just return an Observable<Fifa[]> you should use a map operator on your Observable:
return this.httpClient.get<GetResponse>(fifaUrl).pipe(
map((response) => response.fifa)
);
update the return type to Observable<GetResponse> then you need to map the respond to GetResponse structure
fetchAllGamesRecordPaginate(pageNumber:number,pageSize: number):Observable<GetResponse>{
const fifaUrl = ${this.baseUrl}/demo/pageNumber/${pageNumber}/pageSize/${pageSize};
return this.httpClient.get(fifaUrl)
.pipe(([fifa,paginationInfo]) => (
{
fifa ,
...paginationInfo
}
)
);
}
the api return an array with two items the first is the fifa[] and the
second is an object with pagination information

Destructuring array and accessing the first element

I made and API call using fetch to get JSON data. That data is then passed to my function displayCartTotal, which accepts a parameter that uses de-structuring to obtain results.
In displayCartTotal, I want to de-structure the first item into the results array, into a data variable. Next, use object de-structuring to obtain the itemsInCart and buyerCountry properties of the data.
I have tried de-structuring the array, but is not working, also when i do typeof() on the data I receive, I get "object".
Here is format of the JSON data
{
results: [{
itemsInCart: [{
name: "Jolof Rice",
price: 80,
qty: 2
}, {
name: "Jolof Rice",
price: 80,
qty: 2
}],
buyerCountry: "Uganda"
}],
info: {
seed: "85e0e8ca0e095f74",
results: "1",
page: "1",
version: "0.1",
time: {
instruct: 11,
generate: 5
}
}
}
Code:
const displayCartTotal = ({results}) => {
const [data] = results;
const [itemsInCart,buyerCountry] = data;
return results;
};
const fetchBill = () => {
const api = 'https://randomapi.com/api/006b08a801d82d0c9824dcfdfdfa3b3c';
fetch(api)
.then(response => response.json())
.then(data => displayCartTotal(data))
.catch(error => console.error(error));
};
I expect to de-structure the first item in the results array into a data variable. And also to use object de-structuring to obtain the itemsInCart and buyerCountry properties of data.
Have you tried placing the nth position of the object
const displayCartTotal= ({results})=>{
const {0: data} = results;
const {itemsInCart, buyerCountry} = data;
}

How to alter keys in immutable map?

I've a data structure like this (generated by normalizr):
const data = fromJS({
templates: {
"83E51B08-5F55-4FA2-A2A0-99744AE7AAD3":
{"uuid": "83E51B08-5F55-4FA2-A2A0-99744AE7AAD3", test: "bla"},
"F16FB07B-EF7C-440C-9C21-F331FCA93439":
{"uuid": "F16FB07B-EF7C-440C-9C21-F331FCA93439", test: "bla"}
}
})
Now I try to figure out how to replace the UUIDs in both the key and the value of the template entries. Basically how can I archive the following output:
const data = fromJS({
templates: {
"DBB0B4B0-565A-4066-88D3-3284803E0FD2":
{"uuid": "DBB0B4B0-565A-4066-88D3-3284803E0FD2", test: "bla"},
"D44FA349-048E-4006-A545-DBF49B1FA5AF":
{"uuid": "D44FA349-048E-4006-A545-DBF49B1FA5AF", test: "bla"}
}
})
A good candidate seems to me the .mapEntries() method, but I'm struggling on how to use it ...
// this don't work ... :-(
const result = data.mapEntries((k, v) => {
const newUUID = uuid.v4()
return (newUUID, v.set('uuid', newUUID))
})
Maybe someone can give me a hand here?
mapEntries is the correct method. From the documentation, the mapping function has the following signature:
mapper: (entry: [K, V], index: number, iter: this) => [KM, VM]
This means that the first argument is the entry passed in as an array of [key, value]. Similarly, the return value of the mapper function should be an array of the new key and the new value. So your mapper function needs to look like this:
([k, v]) => {
const newUUID = uuid.v4()
return [newUUID, v.set('uuid', newUUID)]
}
This is equivalent to the following (more explicit) function:
(entry) => {
const key = entry[0]; // note that key isn't actually used, so this isn't necessary
const value = entry[1];
const newUUID = uuid.v4()
return [newUUID, value.set('uuid', newUUID)]
}
One thing to note is that the templates are nested under the templates property, so you can't map data directly -- instead you'll want to use the update function.
data.update('templates', templates => template.mapEntries(...)))
So putting everything together, your solution should look like the following:
const result = data.update('templates', templates =>
templates.mapEntries(([k, v]) => {
const newUUID = uuid.v4()
return [newUUID, v.set('uuid', newUUID)]
})
);