Issue with converting JS object to array - javascript

Here is the one which i am trying to achieve.
I have the below JSON response. I am using $.getJSON method to loads JSON data and adding it in the collection by checking whether it is array as below.
{
"r": [{
"IsDefault": false,
"re": {
"Name": "Depo"
},
"Valid": "Oct8, 2013",
"Clg": [{
"Name": "james",
"Rate": 0.05
}, {
"Name": "Jack",
"Rate": 0.55
}, {
"Name": "Mcd",
"Rate": 0.01,
}],
},
{
"IsDefault": false,
"re": {
"Name": "Depo"
},
"Valid": "Oct8, 2013",
"Clg": [{
"Name": "james",
"Rate": 0.05
}, {
"Name": "Jack",
"Rate": 0.55
}, {
"Name": "Mcd",
"Rate": 0.01,
}],
},
{
"IsDefault": false,
"re": {
"Name": "Depo"
},
"Valid": "Oct8, 2013",
"Clg": [{
"Name": "james",
"Rate": 0.05
}, {
"Name": "Jack",
"Rate": 0.55
}, {
"Name": "Mcd",
"Rate": 0.01,
}],
}]
}
I am passing the json responses on both loadFromJson1 and loadFromJson2 function as parameter as below.
var tablesResult = loadFromJson1(resultstest.r[0].Clg);
loadFromJson1 = function (input) {
if (_.isArray(input)) {
alert("loadFromJson1: Inside array function");
var collection = new CompeCollection();
_.each(input, function (modelData) {
collection.add(loadFromJson1(modelData));
});
return collection;
}
return new CompeModel({
compeRates: loadFromJson2(input),
compName: input.Name
});
};
loadFromJson2 = function (input)
// here is the problem, the 'input' is not an array object so it is not going to IF condition of the isArray method. Hence i am trying to convert into array object.
{
if (_.isArray(input)) {
alert("loadFromJson2: Inside array function");
//alert is not coming here though it is array
var rcollect = new rateCollection();
_.each(input, function (modelData) {
rcollect.add(modelData);
});
return rcollect;
}
};
The above code i am passing json responeses for both loadFromJson1 and loadFromJson2 function as "input". isArray is getting true on only loadFromJson1 function and giving alert inside the if condition but not coming in loadFromJson2 function though i am passing the same parameter.
can you please tell me what mistakes i am doing here?

Your code is a bit scattered and the function loadFromJson1 is duplicted. Also some objects are not posted in de question.
I did however created a fiddle which work; "Inside array function" is printed...
simpliefied version of loadFromJson1 which is working in the fiddle:
loadFromJson1 = function (input) {
var resArray = $.map(input, function (value, index) {
return [value];
});
if (_.isArray(resArray)) {
console.log("Inside array function");
}
};

Related

How do you delete an empty array from javascript?

For reference I have zero javascript knowledge or any coding knowledge. I typically just hook up applications via IPASS applications that don't require any coding knowledge. However, I found out I need to inject some javascript into the application in order to avoid an error message.
I have the below JSON record.
I need to get rid of the empty array (sorry... if it is not an array but an object? Like I said, no javascript knowledge).
In the below code essentially what I want is to completely delete this line, because there is nothing inside the brackets and it is causing errors:
"lineitemsdata": []
Full JSON record below for reference
"id": "5399286500",
"properties": {
"state": "AB",
"website": null,
"zip": "T3B5Y9"
},
"createdAt": "2021-02-18T22:13:06.111Z",
"updatedAt": "2021-05-17T14:35:09.540Z",
"archived": false,
"associations": {
"deals": {
"results": [
{
"id": "5230410841",
"type": "company_to_deal"
}
]
}
},
"dealdata": [
{
"id": "5230410841",
"properties": {
"hs_lastmodifieddate": "2021-05-13T14:00:33.101Z",
"hs_object_id": "5230410841",
"hubspot_owner_id": "52200226"
},
"associations": {
"line items": {
"results": [
{
"id": "1468189759",
"type": "deal_to_line_item"
},
{
"id": "1468189760",
"type": "deal_to_line_item",
"lineitemsdata": []
}
]
}
}
}
],
"DealOwner": [
{
"id": "52200226",
"email": "email#email.com",
"firstName": "Bob"
}
],
"NetSuiteCustomerID": 1745
}
Item inside object is called a property. If you (for some reason) have to include the property, but don't want it to have any value you can either set it's value to null or undefined.
I suspect I'm going to get criticized for this, but here is a quick and dirty way of removing this specific problem through string replacement. The 'right' way would be to break down your json into separte objects until you get to the level where the offending object lives, remove it, then rebuild it all back. For what it's worth, here's an alternative to that
let json = {
"id": "5399286500",
"properties": {
"state": "AB",
"website": null,
"zip": "T3B5Y9"
},
"createdAt": "2021-02-18T22:13:06.111Z",
"updatedAt": "2021-05-17T14:35:09.540Z",
"archived": false,
"associations": {
"deals": {
"results": [{
"id": "5230410841",
"type": "company_to_deal"
}]
}
},
"dealdata": [{
"id": "5230410841",
"properties": {
"hs_lastmodifieddate": "2021-05-13T14:00:33.101Z",
"hs_object_id": "5230410841",
"hubspot_owner_id": "52200226"
},
"associations": {
"line items": {
"results": [{
"id": "1468189759",
"type": "deal_to_line_item"
},
{
"id": "1468189760",
"type": "deal_to_line_item",
"lineitemsdata": []
}
]
}
}
}],
"DealOwner": [{
"id": "52200226",
"email": "email#email.com",
"firstName": "Bob"
}],
"NetSuiteCustomerID": 1745
}
json = JSON.stringify(json)
let strstart = json.indexOf('"lineitemsdata":[]');
let commapos = json.lastIndexOf(',', strstart);
json = json.substr(0, commapos) + " " + json.substr(commapos + 1);
json = json.replace('"lineitemsdata":[]', '');
json = JSON.parse(json)
console.log(json)
You can use this to strip any empty lineitems arrays from your json.
Assuming the reference to your record is json
for(dealIdx in json.dealdata) {
for (resultIdx in json.dealdata[dealIdx].associations["line items"].results) {
let lineItemsData = json.dealdata[dealIdx].associations["line items"].results[resultIdx].lineitemsdata
if (lineItemsData != undefined && lineItemsData.length === 0 ) {
delete json.dealdata[dealIdx].associations["line items"].results[resultIdx].lineitemsdata
}
}
}

lodash pick object fields from array

I have array of objects:
var results= [
{
"_type": "MyType",
"_id": "57623535a44b8f1417740a13",
"_source": {
"info": {
"year": 2010,
"number": "string",
},
"type": "stolen",
"date": "2016-06-16T00:00:00",
"createdBy": "57469f3c71c8bf2479d225a6"
}
}
];
I need to select specific fields from array. In result, I want to get the following:
[
{
"_id": "57623535a44b8f1417740a13",
"info": {
"year": 2010,
"number": "string"
},
"type": "stolen",
"date": "2016-06-16T00:00:00",
"createdBy": "57469f3c71c8bf2479d225a6"
}
]
As you can see, I want to select _id field and content of _source object. How can I do this with lodash?
I've found .map function, but it doesn't take array of keys:
var res = _.map(results, "_source");
You could do:
var mapped = _.map(results, _.partialRight(_.pick, ['_id', 'info', 'type', 'date', 'createdBy']));
A little explanation:
_.map(): Expects a function which takes each item from the collection so that you can map it to something else.
_.partialRight(): Takes a function which will be called later on with the its arguments appended to the end
_.pick(): Gets the path specified from the object.
In plain Javascript you could iterate with Array#map and assemble a new object for each object without mutilation the original object.
var results = [{ "_type": "MyType", "_id": "57623535a44b8f1417740a13", "_source": { "info": { "year": 2010, "number": "string", }, "type": "stolen", "date": "2016-06-16T00:00:00", "createdBy": "57469f3c71c8bf2479d225a6" } }],
res = results.map(function (a) {
var o = { _id: a._id };
["info", "type", "date", "createdBy"].forEach(function (k) {
o[k] = a._source[k];
});
return o;
});
console.log(res);
I had the same requirement, and the below solution worked best for me.
let users = [
{
"_id": "5ead7783ed74d152f86de7b0",
"first_name": "User First name 1",
"last_name": "User Last name 1",
"email": "user1#example.com",
"phone": 9587788888
},
{
"_id": "5ead7b780d4bc43fd0ef92e7",
"first_name": "User FIRST name 1",
"last_name": "User LAST name 1",
"email": "user2#example.com",
"phone": 9587788888
}
];
users = users.map(user => _.pick(user,['_id','first_name']))
console.log(users)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
var results = [{
_type: "MyType",
_id: "57623535a44b8f1417740a13",
_source: {
info: {
year: 2010,
number: "string",
},
type: "stolen",
date: "2016-06-16T00:00:00",
createdBy: "57469f3c71c8bf2479d225a6"
}
}];
var rootProperty = ['_id']
var innerProperty = '_source'
var myArray = _.map(results, result => _(result)
.pick(rootProperty)
.assign(_.result(result, innerProperty))
.value()
)
console.log(myArray)
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
You can map() the result and have each item assign() the _id key-value in an object toegether with the _source object.
results = _.map(results, item => _.assign(
{ _id: item._id },
item._source
));
var results = [{
"_type": "MyType",
"_id": "57623535a44b8f1417740a13",
"_source": {
"info": {
"year": 2010,
"number": "string",
},
"type": "stolen",
"date": "2016-06-16T00:00:00",
"createdBy": "57469f3c71c8bf2479d225a6"
}
}];
results = _.map(results, item => _.assign(
{ _id: item._id },
item._source
));
document.write('<pre>' + JSON.stringify(results, 0, 4) + '</pre>');
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
You may also choose to write this in plain JS:
result = results.map(item => Object.assign(
{ _id: item._id }, item._source
));
var results = [{
"_type": "MyType",
"_id": "57623535a44b8f1417740a13",
"_source": {
"info": {
"year": 2010,
"number": "string",
},
"type": "stolen",
"date": "2016-06-16T00:00:00",
"createdBy": "57469f3c71c8bf2479d225a6"
}
}];
result = results.map(item => Object.assign(
{ _id: item._id }, item._source
));
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
To correctly fulfill the OP's question and for even more complex requirements, the application of a schema and a small lodash mixin is invaluable.
The JavaScript is a little ugly, but it looks swell in CoffeeScript (yes, that was a thing once). The compiled JavaScript is hidden beneath.
_.mixin mapGet: (obj, schema) ->
result = for row in input
row_result = {}
for key, value of schema
row_result[key] = _.get(row, value)
row_result
_.mixin({ mapGet: function(obj, schema) {
var key, result, row, row_result, value;
return result = (function() {
var i, len, results;
results = [];
for (i = 0, len = input.length; i < len; i++) {
row = input[i];
row_result = {};
for (key in schema) {
value = schema[key];
row_result[key] = _.get(row, value);
}
results.push(row_result);
}
return results;
})();
}});
/* The remainer is just the proof/usage example */
var expected, input, schema;
input = [{
"_type": "MyType",
"_id": "57623535a44b8f1417740a13",
"_source": {
"info": {
"year": 2010,
"number": "string"
},
"type": "stolen",
"date": "2016-06-16T00:00:00",
"createdBy": "57469f3c71c8bf2479d225a6"
}}];
expected = [{
"_id": "57623535a44b8f1417740a13",
"info": {
"year": 2010,
"number": "string"
},
"type": "stolen",
"date": "2016-06-16T00:00:00",
"createdBy": "57469f3c71c8bf2479d225a6"
}];
schema = {
"_id": "_id",
"info": "_source.info",
"type": "_source.type",
"date": "_source.date",
"createdBy": "_source.createdBy"
};
console.log('expected result: ' + JSON.stringify(expected, 0, 4));
console.log('actual result: ' + JSON.stringify(_.mapGet(input, schema), 0, 4));
<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>
Usage:
schema = {
"_id" : "_id",
"info" : "_source.info",
"type" : "_source.type",
"date" : "_source.date",
"createdBy": "_source.createdBy",
}
_.mapGet(input, schema)
Resultant output:
[{
"_id": "57623535a44b8f1417740a13",
"info": {
"year": 2010,
"number": "string"
},
"type": "stolen",
"date": "2016-06-16T00:00:00",
"createdBy": "57469f3c71c8bf2479d225a6"
}]
Note: Complex schema can be more easily described if the source JSON is first converted to a flat, dotted, representation via:
jq [leaf_paths as $path | {"key":$path | join("."), "value":getpath($path) }] |from_entries'

How to get nodes of Json using jquery?

I have a JSON and i want to get its node under a Node, but net getting how cani get it: Here is the JSON:
{
"price": {
"VPO": 125,
"MSRP": 129.99,
"ONSALE": 99.97,
"a_bucks": 3.75
},
"short_info": {
"product_name": "MARMOT PRECIP JACKET",
"category": "WOMEN'S",
"weight": {
"lbs": 0.6,
"kg": 0.27
},
"SKU": "KNXSU921",
"part_info": "#46200",
"rating": 4,
"out_of_stock": false
},
"product_variants": {
"XS": {
"Arctic Navy": {
"InStock": true,
"Colorcode": "HMN",
"InStore": {
"NANAIMO": {
"value": "true",
"code": "154"
}
}
},
"Black": {
"InStock": true,
"Colorcode": "HMN",
"InStore": {
"NANAIMO": {
"value": "true",
"code": "154"
}
}
},
"Blue Sea": {
"InStock": true,
"Colorcode": "HMN",
"InStore": {
"NANAIMO": {
"value": "true",
"code": "154"
}
}
},
}
}
}
I want to get Elements's (Nodes) name under XS, i.e. "Arctic Navy", "Black", "Blue Sea" etc.
I have used following code:
$.each(dataObj.product_variants.XS, function (i, item) {
alert(item)
});
But not getting how can i get the required output. Please help.
Thanks in advance.
You don't need jQuery for this. You can use normal JavaScript:
Object.keys(dataObj.product_variants.XS)
This will return an array of the keys. e.g.
[ "Arctic Navy", "Black", "Blue Sea" ]
You can try
$.each(dataObj.product_variants.XS, function (i, item) {
alert(i)
});
It can be achieved through javascript also
for(var i in dataObj.product_variants.XS) {
alert(i)
});
If your dataObj.product_variants.XS would have been array, i would have been index of the element.
Try the following:
Use Object.keys() to get the keys of a object
var keys = Object.keys(dataObj.product_variants.XS);
https://jsfiddle.net/zeoj9xd8/
try
$.each(Object.keys(obj.product_variants.XS), function (i, item) {
alert(item)
});
https://jsfiddle.net/qejss4yj/

Filtering subarray of objects

I need to filter a subarray of elements.
var university = {
"fax": "123345",
"email": "test#test.com",
"url": "www.test.com",
"classes": [
{
"number": "1",
"name": "maths",
"students": [
{
"name": "Max",
"exams": [
{
"date": "2016-01-04T18:32:43.000Z",
"passed": false
},
{
"date": "2016-01-04T18:32:43.000Z",
"passed": true
},
{
"date": "2016-01-04T18:32:43.000Z",
"passed": false
},
{
"date": "2016-01-04T18:32:43.000Z",
"passed": true
}
]
},
{...}
]
},
{...}
]
}
Ok I need to get all the classes without filtering, all the students of each class without filtering, but in the exams array I only need to get the ones that passed.
I tried the following:
university.classes.students.exams.filter(function (el) {
return el.passed
});
But it is not working...
I've googled a solution to this without success...any help would be appreciated.
classes and students are arrays - so you have to loop those as well:
university.classes.forEach(function(uniClass) {
uniClass.students.forEach(function(student) {
student.exams = student.exams.filter(function (el) {
return el.passed;
});
});
});

issue with getting JSON child values by specifying full path

I have the below JSON response
{
"r": [{
"IsDefault": false,
"re": {
"Name": "Depo"
},
"Valid": "Oct8, 2013",
"Clg":[ {
"Name": "james",
"Rate": 0.05
},
{
"Name": "Jack",
"Rate": 0.55
},
{
"Name": "Mcd",
"Rate": 0.01,
}],
},
{
"IsDefault": false,
"re": {
"Name": "Depo"
},
"Valid": "Oct8, 2013",
"Clg": [{
"Name": "james",
"Rate": 0.05
},
{
"Name": "Jack",
"Rate": 0.55
},
{
"Name": "Mcd",
"Rate": 0.01,
}],
},
{
"IsDefault": false,
"re": {
"Name": "Depo"
},
"Valid": "Oct8, 2013",
"Clg": [{
"Name": "james",
"Rate": 0.05
},
{
"Name": "Jack",
"Rate": 0.55
},
{
"Name": "Mcd",
"Rate": 0.01,
}],
}]
}
I am using $.getJSON method to loads JSON data and adding it in collection by checking whether it is array as below . It is working fine as expected.
var res = loadFromJson(result.r);
loadFromJson = function(input) {
if (_.isArray(input)) {
console.log("Inside Array");
var collection = new CompeCollection();
_.each(input, function(modData) {
collection.add(loadFromJson(modData));
console.log("collection length:"+modData.length);
});
return collection;
}
};
But when i try to specify the exact path(r.Clg) of my JSON response it is not even coming to above if condition though it is valid response.
var res = loadFromJson(result.r.Clg);
loadFromJson = function(input) {
if (_.isArray(input)) {
console.log("Inside Array");
var collection = new CompeCollection();
_.each(input, function(modData) {
collection.add(loadFromJson(modData));
console.log("collection length:"+modData.length);
});
return collection;
}
};
What should i do when i need to specify actual or full path?
Can any one tell me what could be the problem when i pass more specific json values?
Thanks in advance.
result.r.Clg doesn't exist. result.r is an array.
If you only wanted to access the first object in the r array, you would do this:
var res = loadFromJson(result.r);
var clg = res[0].Clg;
Or you could loop over all the objects, perhaps capturing all the Clgs in one array:
var clgs = res.map(function (obj) { return obj.Clg; }, []);

Categories