Use data from Quandl API to show in Appsmith table widget - javascript

I am building a web-app and want to connect data from Quandl through its JSON API.
However, the JSON I get from quandl has the column names separate from the data itself, check below:
{
"datatable": {
"data": [
[
"AAPL",
"MRY",
"2020-12-31",
"2020-09-26",
"2020-09-26",
"2021-07-28",
-406000000,
323888000000,
325562500000
]
],
]
],
"columns": [
{
"name": "ticker",
"type": "String"
},
{
"name": "dimension",
"type": "String"
},
{
"name": "calendardate",
"type": "Date"
},
{
"name": "datekey",
"type": "Date"
},
{
"name": "reportperiod",
"type": "Date"
},
{
"name": "lastupdated",
"type": "Date"
},
{
"name": "accoci",
"type": "Integer"
},
{
"name": "assets",
"type": "Integer"
},
{
"name": "assetsavg",
"type": "Integer"
}
]
},
"meta": {
"next_cursor_id": null
}
}
When I use this data in Appsmith, it can not infer the column names. Is there a simple javascript code to combine the column names with the data? Thank you!

This is possible with a simple JS snippet, Now my code written is not that great but will work in this case (Can be optimised)
{{
function() {
let tableData = [];
_.map(_d.datatable.data, (v, i) => {
let set = {}
_.map(v, (x, k) => {
var obj = {[_d.datatable.columns[k].name]: x}
set = {...set, ...obj}
})
tableData.push(set)
})
}()
}}
In the above snippet _d is the data which you receive, We map the array value index with the given column index and create a new object out of it, Also since this is a multiline JS code, In Appsmith we need to write this inside an IIFE like above.

Related

In a nested array of objects and using a value of key 1, get the value of key 2

I have a json file of folders.
folders.json
[
{
"name": "Documents",
"files": [
{
"name": "Quarterly Results",
"type": "Document"
}
]
},
{
"name": "Favourites",
"files": [
{
"name": "Brawl Stars",
"files": [
{
"name": "NS dying in 5 seconds",
"type": "Video"
},
{
"name": "Josiah raping NS",
"type": "Video"
}
]
},
{
"name": "Coding",
"files": [
{
"name": "Coding is so fun",
"type": "Image"
},
{
"name": "I love svelte",
"files": [
{
"name": "REPLs",
"files": [
{
"name": "REPL 1",
"type": "Image"
},
{
"name": "REPL 2",
"type": "Videp"
}
]
},
{
"name": "oh nooo",
"type": "Document"
}
]
}
]
},
{
"name": "Favourites 1",
"type": "Document"
},
{
"name": "Favourites 2",
"type": "Video"
},
{
"name": "Favourites 3",
"type": "Image"
}
]
},
{
"name": "Knowledge Base 1",
"type": "Video"
}
]
Let's say I have the folder "name" in folders.json. I want to find all file names inside it.
For example, given a folder "Favourites", I want to output:
[{name: 'Brawl Stars', files: Array(2)}, {name: 'Coding', files: Array(2)} {"name": "Favourites 1", "type": "Document"}, {"name": "Favourites 2","type": "Video"},{"name": "Favourites 3", "type": "Image"}]
Note: A folder is when there are files inside the same dictionary as name.
Thus, using a value of key: name, output out the values of files in this nested array of objects.
I have tried the following: root.filter(item => item.name === currentFolder).map(item => item.files), where root is the array of objects, currentFolder is the folder "name" in folder.json.
However, this only works for depth of 2, where the folder is not nested in other folders.
I have tried looking for other answers, but all other answers only work for until depth of 2, thus needing help.
I am currently using sveltekit framework, not using jquery.
Try some recursion. Loop over every folder, and return the folder if it is what we want. Otherwise, do the same process for that folder. Just like this:
function getFolder(folders, name) {
for (const folder of folders) {
// skip if this isn't a folder
if (!folder.files) continue;
// if this folder is what we're looking for, then return
if (folder.name === name) return folder;
// else recurse and return if we get a result
const subsearch = getFolder(folder.files, name);
if (subsearch) return subsearch;
}
// if there's no matches, return null
return null
}
const folders = [{name:"Documents",files:[{name:"Quarterly Results",type:"Document"}]},{name:"Favourites",files:[{name:"Brawl Stars",files:[{name:"NS dying in 5 seconds",type:"Video"},{name:"Josiah raping NS",type:"Video"}]},{name:"Coding",files:[{name:"Coding is so fun",type:"Image"},{name:"I love svelte",files:[{name:"REPLs",files:[{name:"REPL 1",type:"Image"},{name:"REPL 2",type:"Videp"}]},{name:"oh nooo",type:"Document"}]}]},{name:"Favourites 1",type:"Document"},{name:"Favourites 2",type:"Video"},{name:"Favourites 3",type:"Image"}]},{name:"Knowledge Base 1",type:"Video"}];
console.log(getFolder(folders, 'Favourites'))
You need to use recursion when you search multiple layers of nested data.
I found a solution here
function findNested(obj, key, value) {
// Base case
if (obj[key] === value) {
return obj;
} else {
var keys = Object.keys(obj); // add this line to iterate over the keys
for (var i = 0, len = keys.length; i < len; i++) {
var k = keys[i]; // use this key for iteration, instead of index "i"
// add "obj[k] &&" to ignore null values
if (obj[k] && typeof obj[k] == "object") {
var found = findNested(obj[k], key, value);
if (found) {
// If the object was found in the recursive call, bubble it up.
return found;
}
}
}
}
}
then you can just do this: (where 'folders' is your data)
findNested(folders, "name", "REPLs").files

I need remove unnecessary json objects form my result json file using javascript

I have result json file with 10000 of lines. inside the one array object there are some unnecessary json object i need remove. I have tried so many ways but it's didn't work for me. herewith the piece line of json file
[
{
"product_id": "easybridge",
"errors": []
},
{
"product_id": "learningstudio",
"errors": []
},
{
"product_id": "pearsontestprep",
"errors": []
},
{
"product_id": "productization",
"errors": []
},
{
"product_id": "equella",
"errors": [
{
"property": "instance.test_ids[1]",
"message": "requires property \"maintenance\"",
"schema": {
"$id": "#/properties/test_ids/items",
],
"properties": {
"trend": {
"$id": "#/properties/test_ids/items/properties/trend",
"examples": [
true
]
},
"display": {
"$id": "#/properties/test_ids/items/properties/display",
"type": "boolean",
"examples": [
true
]
},
"test_id": {
"$id": "#/properties/test_ids/items/properties/test_id",
"type": "string",
},
"test_name": {
"$id": "#/properties/test_ids/items/properties/test_name",
"type": "string",
},
"maintenance": {
"$id": "#/properties/test_ids/items/properties/maintenance",
"type": "boolean",
]
},
"instance": {
"trend": false,
"display": false,
"test_id": "8597ae3c-e2a9-45c7-b279-bde1710681be",
"test_name": "Equella Pearsonresearch Ping Test",
"nrAlertStatus": "enabled",
"test_locations": [
{
"alert_state": false,
"location_name": "AWS_US_WEST_2",
"location_label": "Portland, OR, USA",
"included_to_health": false
}
],
"included_to_health": false,
"critical_alert_threshold": 60
},
"name": "required",
"argument": "maintenance",
"stack": "instance.test_ids[1] requires property \"maintenance\""
{
"product_id": "easybridge",
"errors": []
},
I just need only
{
"product_id": "equella",
"errors": [
{
"property": "instance.test_ids[1]",
"message": "requires property \"maintenance\"",
}
},
if the errors json array is not empty. i don't need even this json how can i remove "schema" json object and other unnecessary json object and arrays specially "schema" json object using java script or java. please help
Loop through the array, look at each object, and create a new array by copying over the data you need.
For instance, I'm taking it you don't care about an object if its array of errors is empty, and that you don't care about the schema ever:
let newJSON = [];
//Assume the json variable is the parsed JSON file you posted.
for (let element of json) {
//Must have at least one error
if (element.errors.length > 0) {
//Create a new object
let newObj = {
"product_id" : element.product_id,
"errors" : []
};
//Add each errror
for (let error of element.errors) {
//Only copy across what we need
newObj.errors.push({
"property" : error.property,
"message" : error.message
});
}
//Add object to our new array of JSON
newJSON.push(newObj);
}
}
//newJSON is your processed JSON output
The easiest solution can be:
const records = [{
"product_id": "learningstudio",
"errors": []
},
{
"product_id": "pearsontestprep",
"errors": []
},
{
"product_id": "equella",
"errors": [{
"property": "instance.test_ids[1]",
"message": "requires property \"maintenance\"",
"schema": {
"$id": "#/properties/test_ids/items",
}
}]
}];
const filteredRecords = records.map((record) => {
record.errors = record.errors.map((error) => {
return {property: error. property, message: error.message};
});
return record;
});
console.log(filteredRecords);
You can use map and destructuring assignment to capture only desired properties
let json = [{"product_id": "equella", "errors": [{"property": "instance.test_ids[1]","message": "requires property \"maintenance\"",'xyz': 'not needed','useless': 'not needed',},{'xyz': 'not needed',}]},]
let op = json.map(({product_id,errors}) =>{
let { property, message } = errors[0]
return { product_id, errors: {property,message}}
})
console.log(op)

cannot update an array of elements via a 2d iteration

I have two arrays of object, the first array (printerChart, around 80 elements) is made of the following type of objects:
[{
printerBrand: 'Mutoh',
printerModel: 'VJ 1204G',
headsBrand: 'Epson',
headType: '',
compatibilty: [
'EDX',
'DT8',
'DT8-Pro',
'ECH',
],
},
....
]
The second array (items, around 500 elements) is made of the following type of objects:
[
{
"customData": {
"brand": {
"value": {
"type": "string",
"content": "hp"
},
"key": "brand"
},
"printer": {
"value": {
"type": "string",
"content": "c4280"
},
"key": "printer"
}
},
"name": "DT8 XLXL",
"image": {
"id": "zLaDHrgbarhFSnXAK",
"url": "https://xxxxxxx.net/images/xxxxxx.jpg"
},
"brandId": "xxxxx",
"companyId": "xxxx",
"createdAt": "2018-03-26T14:39:47.326Z",
"updatedAt": "2018-04-09T14:31:38.169Z",
"points": 60,
"id": "dq2Zezwm4nHr8FhEN"
},
...
]
What I want to do is to iterate via the second array and, if the part of the name of an item (i.e. DT8) is included in an element of the array 'compatibility' of the first array, I would like to include a new properties to it from the element of the first array: printerBrand. I have tried but somehow the iteration doesn't take place correctly. This is what I tried:
items.forEach((item) => {
printerChart.forEach((printer) => {
if (printer.compatibilty.some(compatibleElem => (
item.name.includes(compatibleElem)))) {
item.printerBrand = printer.printerBrand;
} else {
item.printerBrand = '';
}
});
});
What am I doing wrong?
You do
items.items.forEach(...)
Shouldn't you be doing
items.forEach(...)
?
I suggest to initialize item.printerBrand with an empty string and use a nested approach of some for getting a brand and to exit the loops, if found.
This prevents to get an empty string even if there is a brand to assign.
items.forEach((item) => {
item.printerBrand = '';
printerChart.some(printer => {
if (printer.compatibilty.some(compatibleElem => item.name.includes(compatibleElem))) {
item.printerBrand = printer.printerBrand;
return true;
}
});
});

How to iterate through deeply nested objects inside of a JSON?

I know there are plenty of questions about iterating through JSON objects but I haven't found one that quite relates to my exact problem. This is the JSON that I'm trying to iterate through:
psinsights = {
"kind": "pagespeedonline#result",
"id": "/speed/pagespeed",
"responseCode": 200,
"title": "PageSpeed Home",
"score": 90,
"pageStats": {
"numberResources": 22,
"numberHosts": 7,
"totalRequestBytes": "2761",
"numberStaticResources": 16,
"htmlResponseBytes": "91981",
"cssResponseBytes": "37728",
"imageResponseBytes": "13909",
"javascriptResponseBytes": "247214",
"otherResponseBytes": "8804",
"numberJsResources": 6,
"numberCssResources": 2
},
"formattedResults": {
"locale": "en_US",
"ruleResults": {
"AvoidBadRequests": {
"localizedRuleName": "Avoid bad requests",
"ruleImpact": 0.0
},
"MinifyJavaScript": {
"localizedRuleName": "Minify JavaScript",
"ruleImpact": 0.1417,
"urlBlocks": [
{
"header": {
"format": "Minifying the following JavaScript resources could reduce their size by $1 ($2% reduction).",
"args": [
{
"type": "BYTES",
"value": "1.3KiB"
},
{
"type": "INT_LITERAL",
"value": "0"
}
]
},
"urls": [
{
"result": {
"format": "Minifying $1 could save $2 ($3% reduction).",
"args": [
{
"type": "URL",
"value": "http://code.google.com/js/codesite_tail.pack.04102009.js"
},
{
"type": "BYTES",
"value": "717B"
},
{
"type": "INT_LITERAL",
"value": "1"
}
]
}
},
{
"result": {
"format": "Minifying $1 could save $2 ($3% reduction).",
"args": [
{
"type": "URL",
"value": "http://www.gmodules.com/ig/proxy?url\u003dhttp%3A%2F%2Fjqueryjs.googlecode.com%2Ffiles%2Fjquery-1.2.6.min.js"
},
{
"type": "BYTES",
"value": "258B"
},
{
"type": "INT_LITERAL",
"value": "0"
}
]
}
}
]
}
]
},
"SpriteImages": {
"localizedRuleName": "Combine images into CSS sprites",
"ruleImpact": 0.0
}
}
},
"version": {
"major": 1,
"minor": 11
}
};
Now, I'm trying to write a function that iterates through all of the ruleResults objects and returns an array of the localizedRuleName properties. According to the JSON, ruleResults has three member objects (AvoidBadRequests, MinifyJavaScript, and SpriteImages). Each of these has a localizedRuleName property I'm trying to access, but when I print out my array, it's blank. Here's how I've written my function:
function ruleList(results) {
var ruleArray = [];
for(var ruleName in results.formattedResults.ruleResults){
ruleArray[counter] = results.formattedResults.ruleResults[ruleName].localizedRuleName;
}
return ruleArray;
}
console.log(ruleList(psinsights));
Can you guys help me get on the right track? I used basically this same method to iterate through the pageStats of the JSON and it worked perfectly. I'm not sure why I can't get it to work with these deeper nested objects and properties.
your problem is not your iteration, but your undefined variable "counter".
Instead of using a counter can use the "push" function:
function ruleList(results) {
var ruleArray = [];
for(var ruleName in results.formattedResults.ruleResults){
ruleArray.push(results.formattedResults.ruleResults[ruleName].localizedRuleName);
}
return ruleArray;
}
fiddle: https://jsfiddle.net/fo9h56gh/
Hope this helps.
you're probably getting a javascript error since counter is not defined. you can try this:
function ruleList(results) {
var ruleArray = [];
var counter = 0;
for(var ruleName in results.formattedResults.ruleResults){
ruleArray[counter] = results.formattedResults.ruleResults[ruleName].localizedRuleName;
counter++;
}
return ruleArray;
}

Generate sequence from a json

Client have one requirement that, content text should start with a new sequence number for each separate content. For Content JSON, Consider following sample JSON. I will get this JSON in front-end as a response from backend. I'm iterating that JSON recursively, So now I want to create its sequence number while iterating over it. What's the easy way to do that?
var myobj = {
"name": "sample", //1
"def": [ //2
{
"setId": 1, //2.1.1
"setDef": [ //2.1.2
{
"type": "STRING", //2.1.2.1.1
"name": "ABC" //2.1.2.1.2
},
{
"type": "STRING", //2.1.2.2.1
"name": "XYZ" //2.1.2.1.2
}
]
},
{
"setId": 2, //2.2.1
"setDef": [ //2.2.2
{
"type": "STRING", //2.2.2.1.1
"name": "abc" //2.2.2.1.2
},
{
"type": "STRING", //2.2.2.2.1
"name": "xyz" //2.2.2.1.1
}
]
}
],
"property": { //3
{
"color": "red" //3.1.1
},
{
"run": true //3.2.1
},
{
"width": [120, 330, 332] //3.3.1
}
},
listing: true //4
};
Here is my code:
function displayContent(obj) {
jQuery.each(obj, function(key, val) {
recursiveIterObj(key, val, obj);
});
}
function recursiveIterObj(key, val, obj) {
if(!isplain(val)){
setContentData(key, curr_seq, last_seq, "");
$.each(val, function(k,v){
recursiveIterObj(k, v, val);
});
}else{
setContentData(key, curr_seq, last_seq, val);
}
}
function isplain(data) {
return (typeof data === 'string' || typeof data === 'number')?
true:false;
}
function setContentData(key, curr_seq, last_seq, val){
$(".heading").text(key);
$(".sequence").txt(curr_seq); // if this is 2.1.2 or 4
$(".sequence_last").txt(last_seq); // then, this should be 2.1.1 or 3
$(".txt_content").text(val);
}
$(function(){
displayContent(obj);
})
NOTE - Above JSON is a random json from internet.
Properties order in objects are not guaranteed in JavaScript.Only in case of array,you will see sequence while iterating in JavaScript.
Since ECMAScript 2015, using the Map object could be an alternative. A Map share some similarities with an Object and guarantee the keys order.

Categories

Resources