I have json file like this,
{
"data":{
"type": "runjob",
"id": "1",
"inputs": [
{
"name": "input",
"value": "d:\\My\\filestore\\JMJ\\Content\\input.xml"
},
{
"name": "cmd",
"value": "test.js //NoLogo"
},
{
"name": "output",
"value": "d:\\My\\filestore\\JMJ\\Content\\output.xml"
}
],
"disabled": false
}
}
I need to read the velues, input.xml and output.xml using javascript.. How can I get those value?
var stdin = WScript.StdIn.ReadAll();
var json = eval('(' + stdin + ')');
var log = new Log(json.data.inputs[?]);
json.data.inputs is an array (note it's json; as Tushar pointed out, you have had jason in the question). So you can use any technique for accessing or looping through an array that's supported by your environment. It look slike you're using JScript on Windows Script Host; last I checked it didn't even have ES5 features, so perhaps a simple for loop:
var i;
var inputs = json.data.inputs;
for (i = 0; i < inputs.length; ++i ){
// Here, inputs[i].name will be the name ("input", "cmd", "output")
// and inputs[i].value will be the value ("d:\\My\\filestore\\JMJ\\Content\\input.xml", for instance)
}
json.data.inputs is an array containing 3 json objects; you want the value property of the first and the third elements:
json.data.inputs[0].value; // "d:\\My\\filestore\\JMJ\\Content\\input.xml"
json.data.inputs[2].value; // "d:\\My\\filestore\\JMJ\\Content\\output.xml"
Related
I am practising with vainilla JS, fetching some data from a public API, and manipulating the DOM with them.
I am finding a problem i am not sure how to solve.
The object has some null values in some fields , but other times that field contain some information.
When I run a loop over it, it always breaks when it reaches one field with a null value.
I would like to know what the best approach should be.
One might be to "clean" the null values from the object, and store the "new cleaned" object in a variable . But guess that´s not the way to go if the API were big.
My second idea would be to include an if condition in the loop, saying to jump to the next one, if the value found is === null , something like this :
function createSomeCards(myObject) {
for (let i=0; i < myObject.lenght; i++) {
if (value === null) { i = i+1 } else { i = i }
here would go the rest of the code to build the cards
i don`t know if that is the approach (even if my code is waz wrong), or should be different.
The object has an structure similar to this :
myObject = [
{
"Habitat Impacts": "Area closures ",
"Image Gallery": [
{
"src": "anImage.jpg",
"alt": "some text",
"title": "more text"
},
{
"src": null,
"alt": "additional text",
"title": "a title here"
},
{
"src": "otherImg.jpg",
"alt": "imgInfor",
"title": null
}
],
"Management": null,
"Scientific Name": "Urophycis tenuis",
"Species Illustration Photo": {
"src": null,
"alt": "Illustration",
"title": ""
},
"Ecosystem Services": null,
"Servings": "1",
"last_update": "05/19/2021 - 13:04"
}]
I update the comment with the JS code in which I am finding the issue with the Null values
function createCards(myObject) {
let cardContainer = document.getElementById('cardContainer');
for (let i = 0; i < myObject.length; i++) {
aInfoButtonLeft.onclick = function () {
let divSlidAct = document.getElementById('sliderImg')
let imgSlidAct= document.createElement('img');
imgSlidAct.setAttribute('src', myObject[i]['Image Gallery'][i]['src']);
imgSlidAct.append(divSliderActive);
}
}
}
I am going to leave my orignal answer under this one because I think it still relevant.
you have an array in an array and you are not looping over the second array "Image Gallery". Adding a second loop lets you get all the images.
I added a check to see if the src was null. this should stop any errors you get about src being null.
function createCards(myObject) {
let cardContainer = document.getElementById('cardContainer');
for (let i = 0; i < myObject.length; i++) {
for (let x=0; x < myObject[i]["Image Gallery"].length; x++) {
if (myObject[i]['Image Gallery'][x]["src"] === null) {
// the source is empty do nothing
}else{
aInfoButtonLeft.onclick = function () {
let divSlidAct = document.getElementById('sliderImg')
let imgSlidAct= document.createElement('img');
imgSlidAct.setAttribute('src', myObject[i]['Image Gallery'][x]["src"]);
imgSlidAct.append(divSliderActive);
}
}
}
}
}
ORIGNAL ANSWER
You have 2 1 issue.
you have an array in an array and you are not looping over the second array "Image Gallery"
2. the 'src' field is an attribute of an object and not an index of an array.
The fact that you have null values doesn't matter. the loop will continue.
See the code below with comments.
let myObject = [
{
"Habitat Impacts": "Area closures ",
"Image Gallery": [
{
"src": "anImage.jpg",
"alt": "some text",
"title": "more text"
},
{
"src": null,
"alt": "additional text",
"title": "a title here"
},
{
"src": "otherImg.jpg",
"alt": "imgInfor",
"title": null
}
],
"Management": null,
"Scientific Name": "Urophycis tenuis",
"Species Illustration Photo": {
"src": null,
"alt": "Illustration",
"title": ""
},
"Ecosystem Services": null,
"Servings": "1",
"last_update": "05/19/2021 - 13:04"
}];
//loop over my object
for (let i=0; i < myObject.length; i++) {
//loop over the image gallery
for (let x=0; x < myObject[i]["Image Gallery"].length; x++) {
console.log("src: " + myObject[i]["Image Gallery"][x].src); //notice it .src and not ["src"]
console.log("alt: " +myObject[i]["Image Gallery"][x].alt);
console.log("title: " +myObject[i]["Image Gallery"][x].title);
//I commented out this section so the snippet would work
/*
aInfoButtonLeft.onclick = function () {
let divSlidAct = document.getElementById('sliderImg')
let imgSlidAct= document.createElement('img');
imgSlidAct.setAttribute('src', myObject[i]['Image Gallery'][x].src);
imgSlidAct.append(divSliderActive);
*/
}
}
Please change the question title, because you're not looping over an object where there's some null values, but you're looping over an array that only has non-null values in your example. The item of that loop can have a property that is sometimes null. That's a different issue.
You asked about the best approach.
"clean" the null values and store the "new cleaned" object in a variable
This is not necessary and yes, this would blow up your memory usage and would consume time
include an if condition in the loop, saying to jump to the next one, if the null value found
if (item.property === null) {
// jumping to the next item of the loop
continue;
}
// do the processing
You can either jump to the next (continue) or you don't do the processing for that item (you do the processing only if not null) like this:
if (item.property !== null) {
// do the processing
}
You could even be safer if checking properties by hasOwnProperty() like here: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
I recommend using functional programming and filtering the array by using https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter like this - this results in a much clearer code:
// for this you could also use myObject.forEach(), but that's not the question here
for (let i = 0; i < myObject.length; i++) {
// filtering image gallery for items that ...
myObject[i]['Image Gallery'] //
// have a non-null src
.filter(item => item.src !== null) //
// and do for each item that following...
.forEach(item => {
console.log('src: ' + item.src); //notice it .src and not ["src"]
console.log('alt: ' + item.alt);
console.log('title: ' + item.title);
});
}
Essentially what I am trying to achieve here is to check if the Barcode inputted/scanned on the form which is stored in self.trackfile is already in the list of files.
self.files() is an array of arrays, each time the file is added it pushes another array from self.trackfile into self.files(), once all the files have been added into the list they can be 'tracked' and sent back to the server.
I am having trouble getting this to work in IE11 (Compatibility Mode), this works fine in Chrome. I have done some searching around and not found a workaround.
The line var fb = self.files()[x].Barcode(); throws the following error in IE: Object doesn't support property or method 'Barcode'.
If you could help me identify a workaround that would be fantastic!
addFile Script
self.addFile = function () {
var index = 0;
if(index < self.files().length){
var i = 0;
for (x in self.files()){
var fb = self.files()[x].Barcode();
var tb = self.trackfile.Barcode();
if(fb==tb){
i += 1;
}
}
if(i > 0){
alert("Error: File Already Exists in List");
}
else {
self.files.push(new TrackFile(self.trackfile));
}
}
else {
self.files.push(new TrackFile(self.trackfile));
}
}
Example of files()
[
{
"Location": "Location 1",
"TransactionMode": "Send",
"ServicePoint": "Service Point 2",
"Status": "Incomplete / Open",
"Comments": "",
"Barcode": "0123456789",
"BarcodeImageBase64": ""
},
{
"Location": "Location 1",
"TransactionMode": "Send",
"ServicePoint": "ServicePoint 1",
"Status": "Incomplete / Open",
"Comments": "",
"Barcode": "9876543210",
"BarcodeImageBase64": ""
}
]
console.log(self.files()[x]);
Try looping through your array with indexes instead of the for (x in foo) construct. You're probably running into a random property on the prototype of the array that IE adds which obviously wouldn't contain a Barcode.
See: Why is using "for...in" with array iteration a bad idea?
So I figured out how to get around this rather than trying to return a value from a nested array I created an array of just the barcodes:
self.justBarcodes = ko.computed(function() {
var barcodes = ko.utils.arrayMap(this.files(), function(item) {
return item.Barcode();
});
return barcodes.sort();
}, self);
Then I looped through the self.justBarcodes() array to check if the barcode already exists:
for (var x = 0; x < self.justBarcodes().length; x++){
var fb = self.justBarcodes()[x];
var tb = self.trackfile.Barcode();
if(fb==tb){
i += 1;
}
}
Now it works as it should!
I want to convert JSON to HTML to display it on website. I've googled, and this error occurs when when json is a string, and first I need to parse. But when I use JSON.parse, the console says it is already an object (Unexpected token o in JSON at position 1).
$(document).ready(function() {
$("#getMessage").on("click", function() {
$.getJSON("http://quotes.rest/qod.json", function(json) {
var html = "";
json.forEach(function(val) {
var keys = Object.keys(val);
html += "<div class = 'blabla'>";
keys.forEach(function(key) {
html += "<b>" + key + "</b>: " + val[key] + "<br>";
});
html += "</div><br>";
});
$(".message").html(html);
});
});
});
json is an object, not an array. You can use forEach only on arrays.
As you have done already, you can iterate over the object's keys like this:
Object.keys(json).forEach(function(key) {
var value = json[key];
...
});
In addition to what everyone else said, it appears that the JSON response does not look like you think it does.
var json = {
"success": {
"total": 1
},
"contents": {
"quotes": [{
"quote": "It's not whether you get knocked down, it...s whether you get up.",
"length": "65",
"author": "Vince Lombardi",
"tags": [
"failure",
"inspire",
"learning-from-failure"
],
"category": "inspire",
"date": "2016-08-09",
"title": "Inspiring Quote of the day",
"background": "https://theysaidso.com/img/bgs/man_on_the_mountain.jpg",
"id": "06Qdox8w6U3U1CGlLqRwFAeF"
}]
}
};
var messageEl = document.querySelector('.message');
messageEl.innerText = json.contents.quotes[0].quote;
<div class="message"></div>
$.getJson already transforms a JSON object into a javascript object, so you would not need to parse it again.
However, your problem starts with forEach, which is an Array method, not an Object method, therefor it will not work in your use case.
var jsonKeys = Object.keys(json); jsonKeys.forEach(...) will work, as Object.keys returns an array of Object keys.
From this query to the Wikipedia API:
http://en.wikipedia.org/w/api.php?action=query&prop=links&format=json&plnamespace=0& pllimit=10&titles=List%20of%20television%20programs%20by%20name
I get a JSON structure, e.g.:
var data = {
"query": {
"pages": {
"1536715": {
"pageid": 1536715,
"ns": 0,
"title": "List of television programs by name",
"links": [
{
"ns": 0,
"title": "$1.98 Beauty Show"
},
{
"ns": 0,
"title": "''Dance Academy''"
}
]
}
}
},
"query-continue": {
"links": {
"plcontinue": "1536715|0|15\/Love"
}
}
}
I want to work with the elements of the "links" array. However, based on the existence of the element "pageid": 1536715, I suspect the name of the nested object "1536715" is a dynamic value that may change. I am reluctant to use this name to access the "links" array, e.g. query.pages.1536715.links.
Is there any way to "step" past this object, i.e. with a wild card query.pages.*.links? Failing that, can I iterate the children of pages to get this object? I am using jQuery 1.7.2 for this project, in case you can suggest any helpful methods from there.
Yes, you will need to loop over it. See also the very similiar question parse json string from wikimedia using jquery. You could also receive a list of result pageids using the indexpageids parameter.
if (data && data.query && data.query.pages)
var pages = data.query.pages;
else
// error: No pages returned / other problems!
for (var id in pages) { // in your case a loop over one property
var links = pages[id].links
if (links)
for (i=0; i<links.length; i++) {
// do what you want with links[i]
}
else
// error: No links array returned for whatever reasons!
}
This should get you there...
var links, i, pageID;
for (pageID in query.pages) {
links = query.pages[pageID].links;
for (i=0; i<links.length; i++) {
link = links[i];
link.ns; link.title // handle link obj here.
}
}
I have nested JSON object like
{"baseball":
{"mlb":
{"regular":
{"_events": [{"start_time": "2011-07-31 17:35", "lines":
[{"comment": "", "coeff": "2.35", "title": "2", "old_coeff": "2.35", "is_main": true},
{"comment": "", "coeff": "1.59", "title": "2", "old_coeff": "1.59", "is_main": true},
{"comment": "", "coeff": "1.59", "title": "2", "old_coeff": "1.59", "is_main": true},
{"comment": "", "coeff": "2.35", "title": "2", "old_coeff": "2.35", "is_main": true}],
"members": ["atlanta", "florida"]
}
]
}}}}
And i need get _events array and parse it too. But I don't know what will be in cells before _events and how they will. How do I work with this structure?
function recursiveGetProperty(obj, lookup, callback) {
for (property in obj) {
if (property == lookup) {
callback(obj[property]);
} else if (obj[property] instanceof Object) {
recursiveGetProperty(obj[property], lookup, callback);
}
}
}
And just use it like this:
recursiveGetProperty(yourObject, '_events', function(obj) {
// do something with it.
});
Here's a working jsFiddle: http://jsfiddle.net/ErHng/ (note: it outputs to the console, so you need to Ctrl+Shift+J/Cmnd+Option+I in chrome or open firebug in Firefox and then re-run it)
If the structure is known:
Assuming that you have the above in a String called input (and that the JSON is valid):
var obj = JSON.parse(input) // converts it to a JS native object.
// you can descend into the new object this way:
var obj.baseball.mlb.regular._events
As a warning, earlier versions of IE do not have JSON.parse, so you will need to use a framework for that.
If the structure is unknown:
// find the _events key
var tmp = input.substr(input.indexOf("_events"))
// grab the maximum array contents.
tmp = tmp.substring( tmp.indexOf( "[" ), tmp.indexOf( "]" ) + 1 );
// now we have to search the array
var len = tmp.length;
var count = 0;
for( var i = 0; i < len; i++ )
{
var chr = tmp.charAt(i)
// every time an array opens, increment
if( chr == '[' ) count++;
// every time one closes decrement
else if( chr == ']' ) count--;
// if all arrays are closed, you have a complete set
if( count == 0 ) break;
}
var events = JSON.parse( tmp.substr( 0, i + 1 ) );
The easiest thing to do in this situation, I find, is to go to JSFiddle, paste in your json as a variable:
var json = {"baseball": ... etc.
console.log(json);
Then using Chrome, "View" -> "Developer" -> "Javascript console" start to experiment with what the data structure looks like in order to build up your parsing function.
Then start experimenting with the structure. Eg.
console.log(json.baseball.mlb.regular._events);
Or if you turn on JQuery:
$.each(json.baseball.mlb.regular._events, function(i, item){
$.each(item.lines,function(i,line){
console.log(line.coeff);
});
});
If you're having trouble actually loading in this JSON into a variable you'll need to JSON.parse a string retrieved via an AJAX call I suspect.