I'm calling the below Parse Query using the Parse Server Javascript API. I have a class called Device, which has a pointer object to Device_Type which in turn has a pointer to Manufacturer.
I can successfully display the deviceID in inventoryItem, but get undefined for manufacturer, despite there being the relevant data in the JSON network return.
$scope.getDeviceItems = function () {
var query = new Parse.Query("Device");
query.include("Device_Type");
query.include("Device_Type.Manufacturer");
query.find({
success: function (results) {
$scope.deviceItems = [];
for (i = 0; i < results.length; i++) {
var d = results[i].get("Device_Type");
var m = results[i].get("Device_Type.Manufacturer");
var inventoryItem = {
deviceID: d.get("Device_ID"),
manufacturer: m.get("Manufacturer_Name")
}
};
};
};
};
How would I correctly obtain the nested pointer data into manufacturer?
Here's a sample JSON Object:
{
"results": [{
"objectId": "q3D2myHG3e",
"createdAt": "2017-07-30T22:28:05.035Z",
"updatedAt": "2017-09-19T20:40:05.580Z",
"Device_Type": {
"objectId": "Ksej3F2sdp5",
"Device_Name": "Device 1",
"createdAt": "2017-07-30T21:57:58.638Z",
"updatedAt": "2017-08-08T20:20:14.397Z",
"Manufacturer": {
"objectId": "3NahYBNIiC",
"Manufacturer_Name": "ABC Ltd",
"createdAt": "2017-07-30T21:56:40.557Z",
"updatedAt": "2017-07-30T22:13:07.425Z",
"Devices": {
"__type": "Relation",
"className": "DeviceType"
},
"__type": "Object",
"className": "DeviceManufacturer"
},
"__type": "Object",
"className": "DeviceType"
},
...
}]
}
$scope.getDeviceItems = function () {
var query = new Parse.Query("Device");
query.include("Device_Type");
query.include("Device_Type.Manufacturer");
query.find({
success: function (results) {
$scope.deviceItems = [];
for (i = 0; i < results.length; i++) {
var curResult = results[i];
var d = curResult.Device_Type;
var m = curResult.Device_Type.Manufacturer;
var inventoryItem = {
deviceID: d.Device_ID
manufacturer: m.Manufacturer_Name
}
};
};
};
};
Not sure why a map is being used a regular JS object as shown above would work easier (assuming find function just resolved with the JS object from parsing the JSON instead of turning it into a Map object)
Using a Map you need to call get twice as far as I can tell to resolve "deeper" keys.
$scope.getDeviceItems = function () {
var query = new Parse.Query("Device");
query.include("Device_Type");
query.include("Device_Type.Manufacturer");
query.find({
success: function (results) {
$scope.deviceItems = [];
for (i = 0; i < results.length; i++) {
var curResult = results[i];
var d = curResult.get('Device_Type');
var m = curResult.get('Device_Type').get('Manufacturer'); // or d.get('Manufacturer')
var inventoryItem = {
deviceID: d.get('Device_ID')
manufacturer: m.get('Manufacturer_Name')
}
};
};
};
};
var testObj = new Map();
testObj.set('a', new Map());
testObj.get('a').set('b', 4);
console.log(testObj.get('a').get('b'))
Related
I am trying to loop through an array that is part of a JSON object from a page speed insights call to add all of the unused javascript Urls to a google sheet using the script editor.
Here is an example of the JSON object:
"audits": {
"unused-javascript": {
"id": "unused-javascript",
"title": "Remove unused JavaScript",
"description": "Remove unused JavaScript to reduce bytes consumed by network activity. [Learn more](https://web.dev/unused-javascript/).",
"score": 0.43,
"scoreDisplayMode": "numeric",
"numericValue": 1350,
"numericUnit": "millisecond",
"displayValue": "Potential savings of 231 KiB",
"details": {
"type": "opportunity",
"headings": [
{
"key": "url",
"valueType": "url",
"subItemsHeading": {
"key": "source",
"valueType": "code"
},
"label": "URL"
},
{
"key": "totalBytes",
"valueType": "bytes",
"subItemsHeading": {
"key": "sourceBytes"
},
"label": "Transfer Size"
},
{
"key": "wastedBytes",
"valueType": "bytes",
"subItemsHeading": {
"key": "sourceWastedBytes"
},
"label": "Potential Savings"
}
],
"items": [
{
"url": "https://connect.facebook.net/signals/config/1926350194273730?v=2.9.2=stable",
"totalBytes": 140229,
"wastedBytes": 108197,
"wastedPercent": 77.15757011763822
},
{
"url": "https://static.example.com/domain.us.modern.bundle.a02fef045566caf5d464.js",
"totalBytes": 306716,
"wastedBytes": 106243,
"wastedPercent": 34.63892414884589
},
{
"url": "https://www.googletagmanager.com/gtm.js?id=GTM-KZ",
"totalBytes": 127214,
"wastedBytes": 21845,
"wastedPercent": 17.17151000374831
}
],
"overallSavingsMs": 1350,
"overallSavingsBytes": 236285
}
},
I am attempting to loop through the "items" array within the "unused-javascript" object and get all of the urls to show in google sheets.
Here is the code I have within the script editor. When I run this, only one URL shows on the sheet. However, I am trying to get all of the URLs added to the sheet.
function pageSpeed(Url) {
var key = "AIzaSyAyHY";
var serviceUrl = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=" + Url + "&key=" + key;
var array = [];
if (key == "YOUR_API_KEY")
return "Please enter your API key to the script";
var response = UrlFetchApp.fetch(serviceUrl);
if (response.getResponseCode() == 200) {
var content = JSON.parse(response.getContentText());
if ((content != null) && (content["lighthouseResult"] != null)) {
if (content["captchaResult"]) {
var timetointeractive = content["lighthouseResult"]["audits"]["interactive"]["displayValue"].slice(0, -2);
var firstcontentfulpaint = content["lighthouseResult"]["audits"]["first-contentful-paint"]["displayValue"].slice(0, -2);
var firstmeaningfulpaint = content["lighthouseResult"]["audits"]["first-meaningful-paint"]["displayValue"].slice(0, -2);
var speedindex = content["lighthouseResult"]["audits"]["speed-index"]["displayValue"].slice(0, -2);
var unusedJs = content["lighthouseResult"]["audits"]["unused-javascript"]["details"]["items"];
for (var i = 0; i < unusedJs.items.length; i++) {
var unusedUrl;
unusedUrl = unusedJs[i]["url"]
}
}
else {
var timetointeractive = "An error occured";
var firstcontentfulpaint = "An error occured";
var firstmeaningfulpaint = "An error occured";
var speedindex = "An error occured";
var unusedJs = "An error occured";
}
}
var currentDate = new Date().toJSON().slice(0, 10).replace(/-/g, '/');
array.push([timetointeractive, firstcontentfulpaint, firstmeaningfulpaint, speedindex, currentDate, "complete", unusedUrl]);
Utilities.sleep(1000);
return array;
}
}
Any and all help is appreciated!
You're on the right track.
Take a look below at my usage of Array.prototype.map. That's the simpler route.
Your for loop would work just as well IF you declared unusedUrl outside of (ie. before) the loop AND pushed to an existing array. As it is, there's an issue of scope, so unusedUrl is redeclared on every iteration, meaning you'll only assign the last iteration's value to unusedUrl.
Both solutions are below.
Using map
var content = {
lighthouseResult: {
audits: {
'unused-javascript': {
// Other stuff
details: {
// Other stuff
items: [
{
url:
'https://connect.facebook.net/signals/config/1926350194273730?v=2.9.2=stable',
totalBytes: 140229,
wastedBytes: 108197,
wastedPercent: 77.15757011763822,
},
{
url:
'https://static.example.com/domain.us.modern.bundle.a02fef045566caf5d464.js',
totalBytes: 306716,
wastedBytes: 106243,
wastedPercent: 34.63892414884589,
},
{
url: 'https://www.googletagmanager.com/gtm.js?id=GTM-KZ',
totalBytes: 127214,
wastedBytes: 21845,
wastedPercent: 17.17151000374831,
},
],
overallSavingsMs: 1350,
overallSavingsBytes: 236285,
},
},
},
},
}
var items = content.lighthouseResult.audits['unused-javascript'].details.items
var unusedUrls = items.map(item => item.url) // OR, using es6, items.map(({ url }) => url)
console.log(unusedUrls)
Using for
var items = content.lighthouseResult.audits['unused-javascript'].details.items
var unusedUrls = []
for (var i = 0; i < items.length; i++) {
unusedUrls.push(items[i]['url'])
}
I'm trying to create an JSON from another JSON using Javascript.
Here is my code.
var data = [{
"Id": "123",
"Name": "Abc",
"Amount": 110000
},
{
"Id": "567",
"Name": "DEF",
"Amount": 98000
},
{
"Id": "345",
"Name": "XYZ",
"Amount": 145000
}
];
finalArray(data);
function finalArray(data) {
var nArray = [];
var subArray = new Object();
subArray.total = 0;
subArray.records = {};
subArray.size = 0;
data.forEach(item => {
subArray.total += item.Amount;
subArray.records += item;
subArray.size += 1;
});
nArray.push(subArray);
console.log(nArray);
};
Here In the final object, In records I'm getting the below output.
records: "[object Object][object Object][object Object][object Object]"
expected output is
records: "[object Object][object Object][object Object]"
where as in my actual data, I've 3 records in the input.
Please let me know where I'm going wrong.
Thanks
This should work.
function finalArray(data) {
var nArray = [];
var subArray = new Object();
subArray.total = 0;
subArray.records = []; // records must be array
subArray.size = 0;
data.forEach(item => {
subArray.total += item.Amount;
subArray.records.push(item); // need to push each item to records array
subArray.size += 1;
});
nArray.push(subArray);
console.log(nArray);
};
Code has 2 mistakes.
record should be an array not an object
you need use push method to add data to record. Not addition assignment (+=)
var data = [{
"Id": "123",
"Name": "Abc",
"Amount": 110000
},
{
"Id": "567",
"Name": "DEF",
"Amount": 98000
},
{
"Id": "345",
"Name": "XYZ",
"Amount": 145000
}
];
finalArray(data);
function finalArray(data) {
var nArray = [];
var subArray = new Object();
subArray.total = 0;
subArray.records = [];
subArray.size = 0;
data.forEach(item => {
subArray.total += item.Amount;
subArray.records.push(item);
subArray.size += 1;
});
nArray.push(subArray);
console.log(nArray);
};
Change your function to this-
function finalArray(data) {
var nArray = [];
var subArray = new Object();
subArray.total = 0;
subArray.records=[];
subArray.size = 0;
data.forEach(item => {
subArray.total += item.Amount;
subArray.records += item;
subArray.size += 1;
});
nArray.push(subArray);
console.log(nArray);
};
Use an array to hold the original items.
Also, you'll need push to add an Object to an Array;
var data = [{
"Id": "123",
"Name": "Abc",
"Amount": 110000
},
{
"Id": "567",
"Name": "DEF",
"Amount": 98000
},
{
"Id": "345",
"Name": "XYZ",
"Amount": 145000
}
];
finalArray(data);
function finalArray(data) {
// New data
let nArray = {};
nArray.total = 0;
nArray.size = 0;
// Create an array inside nArray to hold original items
nArray.records = [];
data.forEach((item) => {
nArray.total += item.Amount;
nArray.size += 1;
nArray.records.push(item);
});
console.log(nArray);
};
I have WEbDataconnector in Javascript, which download data from .json file and load table:
myConnector.getData = function(table, doneCallback) {
$.getJSON("http://url/api/opls/number/tasks?apiKey", function(resp) {
var feat = resp.data,
tableData = [];
// Iterate over the JSON object
var keys = Object.keys(feat);
for (var i = 0, len = keys.length; i < len; i++) {
tableData.push({
"taskId": feat[keys[i]].taskId,
"owner": feat[keys[i]].owner,
"description": feat[keys[i]].description,
"responsible": feat[keys[i]].responsible,
});
}
table.appendRows(tableData);
doneCallback();
});
My problem is that i have multiple URL, with different numbers and apikeys. And i need combine data from all URLs into one table.
Could anyone please help me out? Thank you.
edit:
If i add more elements to data.push() method it ends with:"null is not an object" because some objects in JSON are null,
example of JSON:
"1026533": {
"taskId": 1026533,
"opl": 6919,
"owner": "name",
"description": "text",
"responsible": "name",
"taskStart": {
"date": "2016-03-21 13:28:11.000000",
"timezone_type": 3,
"timezone": "Europe\/Prague"
but sometimes there is an element taskStart with null:
"1026535": {
"taskId": 1026535,
"opl": 6919,
"owner": "name",
"description": "text",
"responsible": "name",
"taskStart": null,
how can i check this and push all data or null? thank you
Use recursion and named function expression with a list of URL.
myConnector.getData = function (table, doneCallback) {
var urls = [ /* the urls */]
if (urls.length == 0) return doneCallback();
$.getJSON(urls.shift(), function callback(resp) {
var feat = resp.data,
tableData = [];
// Iterate over the JSON object
var keys = Object.keys(feat);
for (var i = 0, len = keys.length; i < len; i++) {
tableData.push({
"taskId": feat[keys[i]].taskId,
"owner": feat[keys[i]].owner,
"description": feat[keys[i]].description,
"responsible": feat[keys[i]].responsible,
});
}
table.appendRows(tableData);
var url = urls.shift();
if (url) return $.getJSON(url, callback); // recursion happens here
doneCallback();
});
}
Keep an array containing all the urls that you need to fetchs.
urls = [
'http://url/api/opls/number1/tasks?apiKey1',
'http://url/api/opls/number2/tasks?apiKey2',
'http://url/api/opls/number3/tasks?apiKey3'
];
Then iterate over the array and send an ajax request on each url.
urls.forEach(function(url) {
$.getJSON(url, function(resp) {
var feat = resp.data,
let data = [];
// Iterate over the JSON object
var keys = Object.keys(feat);
for (var i = 0, len = keys.length; i < len; i++) {
data.push({
"taskId": feat[keys[i]].taskId,
"owner": feat[keys[i]].owner,
"description": feat[keys[i]].description,
"responsible": feat[keys[i]].responsible,
});
}
table.appendRows(data);
doneCallback();
});
});
This is a two part question that I can't seem to solve. Part one requires that the entire object belonging to 'Theo' is removed somehow. Part two needs the object changed by editing one of the properties values belonging to 'Lorie'. Here's the array and instructions:
var employees = [{
"firstName": "Von",
"lastName": "Budibent",
"email": "vbudibent0#163.com",
"department": "Sales"
}, {
"firstName": "Catherina",
"lastName": "Swalowe",
"email": "cswalowe1#example.com",
"department": "Engineering"
}, {
"firstName": "Theo",
"lastName": "Trill",
"email": "ttrill2#sina.com.cn",
"department": "Services"
}, {
"firstName": "Elsy",
"lastName": "McCrorie",
"email": "emccrorie3#netscape.com",
"department": "Legal"
}, {
"firstName": "Lorie",
"lastName": "Handsheart",
"email": "lhandsheart4#fotki.com",
"department": "Research and Development"
}]
/* Create a function called 'employeeUpdater'. employeeUpdater will loop
over the array above and perform the following:
1. If employee's first name is Theo, remove that employee because he just
got fired.
2. If the employee's first name is Lorie, change her department to 'HR'.
3. Return the updated employee array. */
All I have to start is the following:
var employeeUpdater = () => {
for (let i = 0; i < employees.length; i++) {
if (employees[i] = 'Theo') {
employees.remove(employees[i]);
} else if (employees[i] = 'Lorie') {
employees.department = 'HR';
}
} return employees;
}
Something is wrong with the code
Javascript arrays don't have an method with name remove, instead you need to use Array#splice method for removing an item. But I can suggest this solution.
First use Array#filter to exclude the objects with name Theo then use Array#map or Array#forEach to iterate over the arrays an find the objects which name with Lorie and change it's department a.
var employees = [{
"firstName": "Von",
"lastName": "Budibent",
"email": "vbudibent0#163.com",
"department": "Sales"
}, {
"firstName": "Catherina",
"lastName": "Swalowe",
"email": "cswalowe1#example.com",
"department": "Engineering"
}, {
"firstName": "Theo",
"lastName": "Trill",
"email": "ttrill2#sina.com.cn",
"department": "Services"
}, {
"firstName": "Elsy",
"lastName": "McCrorie",
"email": "emccrorie3#netscape.com",
"department": "Legal"
}, {
"firstName": "Lorie",
"lastName": "Handsheart",
"email": "lhandsheart4#fotki.com",
"department": "Research and Development"
}];
var editedEmployees = employees
.filter(emp => emp.firstName !== 'Theo')
.map(emp =>
({
"firstName": emp.firstName,
"lastName": emp.lastName,
"email": emp.email,
"department": emp.firstName === 'Lorie' ? 'HR' : emp.department
}));
console.log(editedEmployees)
you can do it with splice():
var employeeUpdater = () => {
for (let i = 0; i < employees.length; i++) {
if (employees[i].firstName == 'Theo') {
employees.splice(i, 1);
i--;
} else if (employees[i].firstName == 'Lorie') {
employees[i].department = 'HR';
}
}
}return employees;
One of the tricky things about referencing objects in arrays is that you need to remember you have to reference them with the array index number and then the object name like employees[2].firstName would be how you reference Theo.
Also, the splice method is best for removing an array as stated above.
I believe the code you were trying to write would look like this:
var employeeUpdater = () => {
for (let i = 0; i < employees.length; i++) {
if (employees[i].firstName === 'Theo') {
employees.splice(i, 1);
} else if (employees[i].firstName === 'Lorie') {
employees[i].department = 'HR';
}
} return employees;
}
You should learn to program in an Object Oriented manner. Perhaps this will help:
//<![CDATA[
var pre = onload;
onload = function(){
if(pre)pre(); // change pre var name if using technique on other pages
var employees = [{
firstName:'Von',
lastName: 'Budibent',
email:'vbudibent0#163.com',
department:'Sales'
}, {
firstName:'Catherina',
lastName:'Swalowe',
email:'cswalowe1#example.com',
department:'Engineering'
}, {
firstName:'Theo',
lastName:'Trill',
email:'ttrill2#sina.com.cn',
department:'Services'
}, {
firstName:'Elsy',
lastName:'McCrorie',
email:'emccrorie3#netscape.com',
department:'Legal'
}, {
firstName:'Lorie',
lastName:'Handsheart',
email:'lhandsheart4#fotki.com',
department:'Research and Development'
}];
function EmployeeHandler(employeeArray){
this.employees = employeeArray;
this.removeByFirstName = function(firstName, caseSensitive){
var emp = this.employees;
var rx = caseSensitive ? new RegExp(firstName) : new RegExp(firstName, 'i');
for(var i=0,l=emp.length; i<l; i++){
if(emp[i].firstName.match(rx)){
this.employees.splice(i, 1);
return this;
}
}
return false;
}
this.removeByLastName = function(lastName, caseSensitive){
var emp = this.employees;
var rx = caseSensitive ? new RegExp(lastName) : new RegExp(lastName, 'i');
for(var i=0,l=emp.length; i<l; i++){
if(emp[i].lastName.match(rx)){
this.employees.splice(i, 1);
return this;
}
}
return false;
}
this.getByFirstName = function(firstName, caseSensitive){
var emp = this.employees;
var rx = caseSensitive ? new RegExp(firstName) : new RegExp(firstName, 'i');
for(var i=0,l=emp.length,em; i<l; i++){
em = emp[i];
if(em.firstName.match(rx)){
return em;
}
}
return false;
}
this.getByLastName = function(lastName, caseSensitive){
var emp = this.employees;
var rx = caseSensitive ? new RegExp(lastName) : new RegExp(lastName, 'i');
for(var i=0,l=emp.length,em; i<l; i++){
em = emp[i];
if(em.lastName.match(rx)){
return em;
}
}
return false;
}
}
var eh = new EmployeeHandler(employees);
var bb = eh.removeByFirstName('Theo').getByLastName('Budibent');
bb.department = 'Intelligent Design';
console.log(eh.employees); console.log(bb); console.log(eh.employees);
}
//]]>
Try this
var editedEmployees = employees
.filter(emp => emp.firstName !== 'Theo')
.map((emp) => {emp.department = emp.firstName === 'Lorie' ? 'HR' :
emp.department; return emp;});
If you like to work with lodash you can make your code easier to read.
So your script should become like this:
var _ = require('lodash');
/* Remove element */
_.remove(employees, function (employee) { return employee.firstName === 'Theo'; });
/* Get element to change */
var employee = _.find(employees,function (employee) { return employee.firstName === 'Lorie'; });
/* Change element */
employee.firstName = 'HR';
/* Right now employees store the right result */
I am new to this so please bear with me.
Please guide me as to how to create a javascript array which in turn gives me a json like this.
{
"MotorInsurance": [{
"Service": "Compare",
"Data": [{
"Apikey": "1234",
"Process": "Compare",
"TransactionId": "32",
"Type": "New",
"Channel": "1"
}],
"Vehicle": [{
"VehicleCode": "456",
"RTOCode": "AP12",
"RegistrationYear": "2016"
}],
"User":[{
"IPAddress": "66",
"DateTime": "12-06-2016"
}]
}]
}
I have tried this :
var formData = {};
formData['MotorInsurance'] = {};
formData['MotorInsurance']['Service'] = "Compare";
formData['MotorInsurance']['Data'] = {};
formData['MotorInsurance']['Data']['Apikey'] = '1234';
formData['MotorInsurance']['Data']['Process'] = 'Compare';
formData['MotorInsurance']['Data']['TransactionId'] = '32';
formData['MotorInsurance']['Data']['Type'] = 'New';
formData['MotorInsurance']['Data']['Channel'] = '1';
formData['MotorInsurance']['Vehicle'] = {};
formData['MotorInsurance']['Vehicle']['VehicleCode'] = '';
formData['MotorInsurance']['Vehicle']['RTOCode'] = '';
formData['MotorInsurance']['Vehicle']['RegistrationYear'] = '';
formData['MotorInsurance']['User'] = {};
formData['MotorInsurance']['User']['IPAddress'] = '66.12.5.4';
formData['MotorInsurance']['User']['DateTime'] = '12-06-2016';
Please guide me. Thanks
var formData = {};
formData['MotorInsurance'] = [{}];
formData['MotorInsurance'][0]['Service'] = "Compare";
formData['MotorInsurance'][0]['Data'] = [{}];
formData['MotorInsurance'][0]['Data'][0]['Apikey'] = '1234';
formData['MotorInsurance'][0]['Data'][0]['Process'] = 'Compare';
formData['MotorInsurance'][0]['Data'][0]['TransactionId'] = '32';
formData['MotorInsurance'][0]['Data'][0]['Type'] = 'New';
formData['MotorInsurance'][0]['Data'][0]['Channel'] = '1';
formData['MotorInsurance'][0]['Vehicle'] = [{}];
formData['MotorInsurance'][0]['Vehicle'][0]['VehicleCode'] = '';
formData['MotorInsurance'][0]['Vehicle'][0]['RTOCode'] = '';
formData['MotorInsurance'][0]['Vehicle'][0]['RegistrationYear'] = '';
formData['MotorInsurance'][0]['User'] = [{}];
formData['MotorInsurance'][0]['User'][0]['IPAddress'] = '66.12.5.4';
formData['MotorInsurance'][0]['User'][0]['DateTime'] = '12-06-2016';
document.write('<pre>' + JSON.stringify(formData, 0, 4) + '</pre>');
Your formData['MotorInsurance'] has to be an array:
formData['MotorInsurance'] = [];
Then you'll be creating everything else in the first element of this array:
formData['MotorInsurance'][0] = {};
formData['MotorInsurance'][0]['Service'] = "Compare";
The same goes for Data, Vehicule and User.
You can approach it like this: for the nested objects, populate them one by one (like the data variable below) and then when assigning to the form data, make sure you put square brackets around the variable.
vehicle = {
"VehicleCode": "456",
"RTOCode": "AP12",
"RegistrationYear": "2016"
};
user = {
"IPAddress": "66",
"DateTime": "12-06-2016"
};
data = {
"Apikey": "1234",
"Process": "Compare",
"TransactionId": "32",
"Type": "New",
"Channel": "1"
};
service = {"Service": "Compare"}
o = {"Data": [data], "Vehicle": [vehicle], "User": [user], "Service": service}
formData["MotorInsurance"] = [o]