Javascript Object Containing Array[1] vs Standard Flat Variable - javascript

I know little about JS, still learning big time. However I am writing a NodeJS app that offers JSON web services to a Angular Frontend.
One problem I have is sometimes my objects have flat name/value pairs and sometimes my objects values will show up in Chromes Console as "address:Array[1]". While I can always do address[0] to get a value, there are parts of my code where I have both that and address: "12345" not sure how to handle it.
I would think it best to have all data output the same way but I cant seem to factor my node code to dump out flat name/value. Nor do I know how to create a Array[1] for a value.
This is the code that creates Array[1] values instead of flat name/value
json.nodes.node.forEach(function (rowData) {
dataObject.push({
name: rowData.name
,address: rowData.address
,enabled: rowData.enabled
})
})
This is the code that creates the flat name/value pairs
for (i = 60; i < 85; i++) {
dataObject.push({
name: i + "f"
,address: i
,enabled: true
})
Any help would be great! Thanks in advance!

Related

Zapier breaks down arrays of objects into distinct arrays containing the keys of the objects

Hi everyone I am having an issue with code by zapier (javascript)... (I know, I know)
The issue I am having is I am bringing in my data from airtable. The data comes in as three distinct arrays. They are:
specCategory[]
specName[]
specDescription[]
I iterate over the arrays and split them out by the commas in the arrays. I then form each of these values in each of the arrays into their own object. I then push that object into an array.
My end goal is to push a JSON payload into PDFMonkey in the form:
{
"payload": [
{
specName: "specName data",
specCategory: "specCategory data",
specDescription: "specDescription data"
},
{
specName: "specName data",
specCategory: "specCategory data",
specDescription: "specDescription data"
},
{
specName: "specName data",
specCategory: "specCategory data",
specDescription: "specDescription data"
}
]
}
Zapier seems to return the correct payload for me. That is, an array of objects. However, when I go to access the data in a subsequent step, the data is returned back into three distinct arrays again.
Here is what the output from the zapier code looks like.
specArray
1
specCategory
Kitchen Appliances
specName
Gas Hob
specDescription
Westinghouse WHG 643 SA Gas Hob
2
specCategory
Kitchen Appliances
specName
Range Hood
specDescription
Westinghouse WRR 614 SA Range Hood
3
specCategory
Kitchen Appliances
specName
Oven
specDescription
Westinghouse WVE 613 S Oven
4
specCategory
Doors and Windows (Internal)
specName
Architraves
specDescription
42X12min Splayed Profile F/Joint Pine painted gloss
5
specCategory
External Stairs
specName
External Stair Balustrade
specDescription
Painted pre-primed ladies waist handrail with slats and bottom rails (not included if stair is under 1m in height)
Instead when accessing it in subsequent steps I receive three distinct arrays like:
specArraySpecName: specName[1],specName[2],specName[...],
specArraySpecCategory: specCategory[1],specCategory[2],specCategory[...],
specArraySpecDescription: specDescription[1],specDescription[2],specDescription[...]
Here is my code so you can have a look and see if what I am doing is wrong. When I try to output just the array of objects (instead of first wrapping the array in object tags) it outputs the single value of each object but the problem is that makes zapier loop the subsequent steps each time using each object as an input.
Is there a way to flatten or stringify the JSON object I am trying to create?
My code below for reference:
// this is wrapped in an async function
// you can use await throughout the function
let categories = inputData.specCategories.split(/\s*,\s*/);
let names = inputData.specName.split(/\s*,\s*/);
let descriptions = inputData.specDescriptions.split(/\s*,\s*/);
let specArray = [];
// for loop to input each of the discrete items into an array
for (let i = 0; i < categories.length; i++) {
let spec = {
specCategory: categories[i],
specName: names[i],
specDescription: descriptions[i]
specArray.push(spec);
}
output = { specArray };
I apologise in advance for the formatting but stack overflow would not let me post code blocks due to some not properly formatted code (tried ctrl + k, 4 space, triple back ticks etc) and I could not figure it out.
Thanks for your help!
Great question! It's worth mentioning that this is Zapier "working as expected"... for use cases that don't match yours. This behavior supports line items, a common structure in Accounting & E-Commerce. But, that doesn't help you, but you want Zapier to stop messing with your nicely structured values.
The best way to handle this is probably to stringify the whole JSON. Zapier only mangles arrays, so it'll leave a JSON string unharmed.
That would be something like this in the code:
// ...
output = { result: JSON.stringify(specArray) };
With any luck, you'll be able to use that payload in a body field for PDFMonkey and it'll process correctly!
But, that's how I share JSON between Zapier steps to keep it un-mangled.

How do I check if an object is within an array in Javascript?

I am getting stuck on a project where I am trying to pull out relevant data from a super massive Google Maps Timeline json, and running into the problem of the structure not being as orderly as I thought it was. Essentially, I am trying to pull out an address, time, date and mileage out of this json for every trip in my car. to use this data, I pasted it into a normal javascript file and named it so I can use it as an object. I then take this data and create a string that will format that info like a CSV file.
From going over the structure of the json by looking at only a few trips, I was able to determine the following general structure:
const google = {
timelineObjects: [
0: {activitySegment: {A NUMBER OF OBJECTS}},
1: {placeVisit : {A NUMBER OF OBJECTS}},
2: {activitySegment: {A NUMBER OF OBJECTS}},
3: {placeVisit : {A NUMBER OF OBJECTS}}
]
}
activitySegment has all the travelling info, like distance, travel times, etc. placeVisit has info about the destination. In my small sample, I was able to just loop through each using an if statement with i%2=0, and just change what I wanted to pull out from each, which worked well.
When I tried adding a larger sample, I was finding that Google occasionally did not create a activitySegment object and only had a placeVisit, which was throwing "Uncaught TypeError: Cannot read property 'distance' of undefined".
I am sure that the even/odd sorting will not work out any more. Is there a way to use a conditional to show if google[timelineObjects][i] is either a {activitySegment} or {placeVisit}? Or, is there a better way to figuring out what object is next in the array?
You can test to see if the Object at the particular array index has a given property using Object.prototype.hasOwnProperty():
const google = {
timelineObjects: [
{activitySegment: {}},
{placeVisit : {}},
{activitySegment: {}},
{placeVisit : {}}
]
};
console.log(google.timelineObjects[0].hasOwnProperty("activitySegment")); // true
console.log(google.timelineObjects[1].hasOwnProperty("activitySegment")); // false
If your objective to see what type of object you get. You can iterate over each object, see what the key of the object is and process the data depending on the key value. Something like this.
Object.entries(google).forEach(([key, value]) => {
if(key==='activitySegment') {
//process activeSegment here
}else {
//process placeVisit here
}
})

why console.log() creating /**id:4**/ and /**ref:4**/ values?

Few mins ago I did this answer and the answer snippet is below
let obj = {staff_changes: []};
let newStaff=[];
for (let i = 0; i < 4; i++) {
newStaff.push({id: 'staff' +i});
obj.staff_changes.push({
id: i,
newStaff: newStaff
});
}
console.log(obj);
If you run this above snippet, you can see /**id:4**/ and /**ref:4**/ . What is this?
When the code on execution time, that was pushing same duplicate values into a array. So I hope at the starting time it's generating a Id:4 and if the same duplicate value will exist, then just it write a comment like /**ref:4**/ where 4 means Id=:4 which is generated already.
So I want to know Is my understand is correct?. If my understanding is correct , then how can we avoid this? Shall I use object.assign() before push the value into array to avoid this?
Your data structure contains multiple references to the same object. console.log is intelligent enough to abbreviate the output.
Note that (AFAIK), the specification does not guarantee any particular output from console.log for objects that aren't instances of String, so you cannot rely on that output being the same across browsers, versions, phases of the moon, etc.
Consider an infinitely recursive data structure like const a = []; a.push(a); console.log(a), which one would you prefer: your computer to lock up while printing an infinitely recursive array or console.log abbreviating it?
const a = []
a.push(a)
console.log(a)
// [
// /**id:1**/
// /**ref:1**/
// ]
Depending on your console tools, they will display an object like this in different ways. Those comments are telling you there is more information deeper in the object.
If you want to see the internals in a consistent way, you can stringify the whole object
console.log(JSON.stringify(obj));
in which case you get:
{"staff_changes":[{"id":0,"newStaff":[{"id":"staff0"},{"id":"staff1"},{"id":"staff2"},{"id":"staff3"}]},{"id":1,"newStaff":[{"id":"staff0"},{"id":"staff1"},{"id":"staff2"},{"id":"staff3"}]},{"id":2,"newStaff":[{"id":"staff0"},{"id":"staff1"},{"id":"staff2"},{"id":"staff3"}]},{"id":3,"newStaff":[{"id":"staff0"},{"id":"staff1"},{"id":"staff2"},{"id":"staff3"}]}]}
In some developer tools, you can expand the object when you log it to the console, but the above string output shows you the whole lot consistently across tools.

Implementing Keras Model into website with Keras.js

I have been trying to implement a basic Keras model generated in Python into a website using the Keras.js library. Now, I have the model trained and exported into the model.json, model_weights.buf, and model_metadata.json files. Now, I essentially copied and pasted test code from the github page to see if the model would load in browser, but unfortunately I am getting errors. Here is the test code. (EDIT: I fixed some errors, see below for remaining ones.)
var model = new KerasJS.Model({
filepaths: {
model: 'dist/model.json',
weights: 'dist/model_weights.buf',
metadata: 'dist/model_metadata.json'
},
gpu: true
});
model.ready()
.then(function() {
console.log("1");
// input data object keyed by names of the input layers
// or `input` for Sequential models
// values are the flattened Float32Array data
// (input tensor shapes are specified in the model config)
var inputData = {
'input_1': new Float32Array(data)
};
console.log("2 " + inputData);
// make predictions
return model.predict(inputData);
})
.then(function(outputData) {
// outputData is an object keyed by names of the output layers
// or `output` for Sequential models
// e.g.,
// outputData['fc1000']
console.log("3 " + outputData);
})
.catch(function(err) {
console.log(err);
// handle error
});
EDIT: So I changed my program around a little to be compatible with JS 5 (that was a stupid mistake on my part), and now I have encountered a different error. This error is caught and then is logged. The error I get is: Error: predict() must take an object where the keys are the named inputs of the model: input. I believe this problem arises because my data variable is not in the correct format. I thought that if my model took in a 28x28 array of numbers, then data should also be a 28x28 array so that it could correctly "predict" the right output. However, I believe I am missing something and that is why the error is being thrown. This question is very similar to mine, however it is in python and not JS. Again, any help would be appreciated.
Ok, so I figured out why this was happening. There were two problems. First, the data array needs to be flattened, so i wrote a quick function to take the 2D input and "flatten" it to be a 1D array of length 784. Then, because I used a Sequential model, the key name of the data should not have been 'input_1', but rather just 'input'. This got rid of all the errors.
Now, to get the output information, we simply can store it in an array like this: var out = outputData['output']. Because I used the MNIST data set, out was a 1D array of length 10 that contained probabilities of each digit being the user-written digit. From there, you can simply find the number with the highest probability and use that as a prediciton for the model.

JSON Data format

Not very familiar with JSON data and how to create it using JavaScript.this is what i am trying
i have created two JS variables
var json={};
var json1={};
i have some certain loops to iterate data and loops like
for(firstLoop){
key=outerKey;
for(innerLook){
innerKey=innerkey;
for(lastloop){
jsonValues= create values in a java variable
}
json[innerKey]=jsonValues;
}
json1[outerKey]=JSON.stringify(json);
}
Doing this i am getting following output
Required: "{"Center":"radio_Required_Center_0,radio_Required_Center_1,","Left":"radio_Required_Left_0,"}"
which is not a valid JSON format.My idea id to create a outer-key say Required and than an inner one's in my case Center and Left
so that i can iterate each value with respect to key Center (i can break the string based on ')
i am not sure how to create correct structure and i don't want to do it on server side which can be done easily.
any solution or hint will really be helpful.
Edit
var data= JSON.stringify(json1);
giving following output
{"Required":"{\"Center\":\"radio_Required_Center_0,radio_Required_Center_1,\",\"Left\":\"radio_Required_Left_0,\"}"}
which is valid JSON data, now i need to execute some code based on the data in the JSON and here are my requirements
Fetch the outer-key (Required or there can be other also).
Fetch all values under the key Center and Left
Create array from the value retrieved from step 2 (split based on ",").
Loop through the values obtained from step 3 and execute the logic.
My real challenge is at step number 2 and 3 where i need to fetch the keys and its associated values and those key and not predefined so i can not access them based on there name.
I am thinking of a way to get key and its values without hard coding key names and execute my logic.
is it possible in by this approach or not?
If you're using a modern version of Javascript, it comes with JSON functions built-in.
var jsonString = JSON.stringify(jsobject);
...to convert a JS object into a JSON string.
(See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify)
and
var jsOject = JSON.parse(jsomString);
...to convert back in the other direction.
(see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/parse)
The only time you need to worry about this not being built-in is if you're using an old browser - for example, older versions of IE. However, in this case, there are polyfill libraries like this one that you can load which will implement the above syntax for you.
If you're just trying to compose one big JSON object, you don't need to stringify one JSON object before adding it to another... So instead of doing JSON.stringify(json) you can just do json1[outerKey]=json
for(firstLoop){
key=outerKey;
for(innerLook){
innerKey=innerkey;
for(lastloop){
jsonValues= create values in a java variable
}
json[innerKey]=jsonValues;
}
json1[outerKey]=json;
}
try jsonlint.com to validate your JSON
This is valid:
{
"Center": "radio_Required_Center_0,radio_Required_Center_1,",
"Left": "radio_Required_Left_0,"
}
This is valid too:
{
"Required": {
"Center": "radio_Required_Center_0,radio_Required_Center_1,",
"Left": "radio_Required_Left_0,"
}
}
This isn't:
Required: {
"Center": "radio_Required_Center_0,radio_Required_Center_1,",
"Left": "radio_Required_Left_0,"
}
using JSON.stringify() is the right way of converting javascript objects to JSON string format. However if you want to put it in a variable you should do that first, later in the last step you convert to JSON string.
var output = { "Required": yourpreviousjsonvar },
jsonString = JSON.strinify(output);
EDIT:
You need to process the data first you probably won't even need the JSON string if I understand you right. (=> if however you already got a string you need it parsed first. Do it using JSON.parse(yourjsonstring))
Fetch the outer-key (Required or there can be other also).
Fetch all values under the key Center and Left
Create array from the value retrieved from step 2 (split based on ",").
Loop through the values obtained from step 3 and execute the logic.
having this as variable:
var a = {
"Required": {
"Center": "radio_Required_Center_0,radio_Required_Center_1,",
"Left": "radio_Required_Left_0,"
}
}
// step 1
console.log(a.Required);
// step 2
console.log(a.Required.Center);
console.log(a.Required.Left);
// step 3
var center = a.Required.Center.split(',');
var left = a.Required.Left.split(',');
// step 4
for(var i = 0; i<center.length; i++){
console.log("doing somthing with", center[i]);
}
Here is a fiddle => use Chrome/safari/Opera's developpertools and check the console to check the output. Or use firebug (in firefox) Or IE9 or greater (F12).
Use native Javascript toSource :
var obj= new Object();
var obj1= new Object();
for(firstLoop){
key=outerKey;
for(innerLook){
innerKey=innerkey;
for(lastloop){
jsonValues= create values in a java variable
}
obj.innerKey=jsonValues;
}
obj1.outerKey=obj;
}
json = obj.toSource();
json1 = obj1.toSource();

Categories