Context
If I have the following JSON data:
{"response":"success","data":[{"id":"2"}]}
I'm trying to get the ID that is sent through, 2.
Attempts
I've tried the following:
var r = JSON.parse('{"response":"success","data":[{"id":"2"}]}');
if(r.response=="success"){
var usr = r.data;
console.log(usr.id);
}
The above outputs undefined.
var r = JSON.parse('{"response":"success","data":[{"id":"2"}]}');
if(r.response=="success"){
var usr = r.data;
for(var k in usr){
if(usr.hasOwnProperty(k)){
console.log(usr.k);
}
}
}
The above outputs undefined.
var r = JSON.parse('{"response":"success","data":[{"id":"2"}]}');
if(r.response=="success"){
var usr = r.data;
var ret = [];
for(var key in usr){
ret.push(key);
}
console.log(ret);
}
The above outputs 0.
var r = JSON.parse('{"response":"success","data":[{"id":"2"}]}');
if(r.response=="success"){
var usr = JSON.parse(r.data);
console.log(usr.id);
}
The above outputs an error - bear in mind this is running via Nativescript so the simulation environment (Android Emulator) may be causing this error:
chromium: [INFO:library_loader_hooks.cc(120)] Chromium logging enabled: level = 0, default verbosity = 0
01-26 19:20:55.423 4875 4875 I BrowserStartupController: Initializing chromium process, singleProcess=true
chromium: [WARNING:resource_bundle.cc(285)] locale_file_path.empty()
01-26 19:20:55.441 4875 4875 E DataReductionProxySettingListener: No DRP key due to exception:java.lang.ClassNotFoundException: com.android.webview.chromium.Drp
chromium: [WARNING:data_reduction_proxy_config.cc(423)] SPDY proxy OFF at startup
Question
How can I access the id property of data in the following JSON string with JavaScript:
{"response":"success","data":[{"id":"2"}]}
You can try with following code. You firstly need to access the data property and then since data is an array, you need an index to access the first elements like data[0] Property and then the id property can be retrieved by r.data[0].id
var r = JSON.parse('{"response":"success","data":[{"id":"2"}]}');
if(r.response === "success"){
console.log(r.data[0].id)
}
You can access console.log(usr[0].id);
Your data value is an array not an object
so on your first attempt, update this:
console.log(usr.id);
to this:
console.log(usr[0].id);
Or you could do a for loop:
if(r.response=="success"){
var usr = r.data;
for(i=0; i < usr.length; i++) {
console.log(usr[i].id);
}
}
Fiddle
Your data object is an array, so you must access first to the position of the array:
usr[0]
the you get the id value
usr[0].id
If you want to access directly with usr.id you need change your JSON data object array to a simple object:
{"response":"success","data":{"id":"2"}}
or make an ugly reasignation:
usr = usr[0]
This is because you have used [] where {} only to be used. If [] is used, then it is an array property, then to access 2, [0].id should be used.
remove [] from [{"id":"2"}]
Related
I am looking for some help, I am working on a piece of code for a client, the client currently have their analytics tag hardcoded to the page with all the key values being sent.
We are in the process of converting them to a new analytics platform using a tag management system, they have been able to update the majority of their platforms to create an object that the new analytics platform can reference but as this site is managed by a 3rd party they are unable to get this resolved in time for our release.
I have managed to successfully pull the tag and split the tag in to parameters:
var x = $('img[alt="MI_TAG"]').attr("src");
x.split("&");
Which creates the array:
1:"109=jsp.searchFlights.initial"
2:"117=Flight Only Journey"
3:"206=02/11/2017"
4:"208=03/11/2017"
5:"212=ALL"
What I want to do is take these array strings to create an object call "mi", like so:
109:"jsp.searchFlights.initial"
117:"Flight Only Journey"
204:""
205:""
206:"02/11/2017"
208:"03/11/2017"
Can someone help?
Thanks all for your help, I have managed to take some of the advice here and create the object and see it logging out:
var x = $('img[alt="MI_TAG"]').attr("src");
var split = x.split("&");
var arrayLength = split.length;
var arr = [];
var i = 0;
do {
arr.push(split[i].replace('=',':'));
arr.toString();
console.log(arr);
i += 1;
} while (i < arrayLength);
let mi = {};
arr.forEach(item=>{
let tempArr = item.split(':');
mi[tempArr[0]] = tempArr[1];
})
console.log(mi);
The issue I now seem to be facing is scope, I want my object to be globally referenceable, how do I do that?
From your array, use reduce - split on the = sign in your string, and create the object:
let newObject = arr.reduce((obj, item) => {
let parts = item.split("=");
obj[parts[0]] = parts[1];
return obj;
}, {});
Assuming you are using at least ECMAScript 5.1 you could use Array.prototype.forEach() to iterate over your array and produce the object.
let myArray = ["109=jsp.searchFlights.initial", "117=Flight Only Journey", "206=02/11/2017", "208=03/11/2017",
"212=ALL"];
let myObject = {};
myArray.forEach(item=>{
let tempArr = item.split('=');
myObject[tempArr[0]] = tempArr[1];
})
console.log(myObject);
Produces:
{
"109": "jsp.searchFlights.initial",
"117": "Flight Only Journey",
"206": "02/11/2017",
"208": "03/11/2017",
"212": "ALL"
}
I'm working on an add-in for excel 2016 using the javascript API. I can successfully get the range into an array and get the values to show in console.log. I've also been able to get the values into a JSON array using JSON.stringify();
I need to manipulate the array to remove the empty values ("").
Can this be accomplished by using regular javascript array methods?
I'm thinking I can display the results back into a different worksheet using a similar approach like i did with var shWk
Here are some snippets of what I'm trying to do:
(function () {
"use strict";
// The initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
$(document).ready(function () {
app.initialize();
//document.getElementById("date").innerHTML = Date("MAR 30 2017");
$('#deleteTab').click(deleteTab);
$('#preview').click(preview);
$('#publish').click(publish);
});
};
function preview() {
Excel.run(function(ctx) {
//getting the colname from a date range in B2
var colName = ctx.workbook.worksheets.getItem('preview').getRange("B2");
colName.load('values');
return ctx.sync().then(function() {
//converting colname value to string for column name
var wkN = (colName.values).toString();
// displaying on the task pane
document.getElementById("tst").innerText = wkN;
// testing to confirm i got the correct colname
var shWk = ctx.workbook.worksheets.getItem('preview').getRange("B3");
shWk.values = colName.values;
//building the column connection by setting the table name located on a different worksheet
var tblName = 'PILOT_ZMRP1';
var tblWK = ctx.workbook.tables.getItem(tblName).columns.getItem(wkN);
//loading up tblWK
tblWK.load('values');
return ctx.sync().then(function(){
//this is where my question is:
var arry = tblWK.values;
for (var i=0; i < tblWK.length; i++){
if (tblWK.values !== ""){
arry.values[i][0]) = tblWK.values[i][0]
};
};
console.log(arry.length); //returns 185
console.log (arry.values);//returns undefined
tblWK.values = arry;
var tblWeek = tblWK.values;
console.log(tblWeek.length);//returns 185
console.log(tblWK.values);//returns [object Array] [Array[1],Array[2]
})
});
}).catch(function (error) {
console.log(error);
console.log("debug info: " + JSON.stringify(error.debugInfo));
});
}
What am I missing? Can you point me to some resources for javascript array handling in the specific context of office.js?
I want to thank everyone for the time spent looking at this question. This is my second question ever posted on Stack Overflow. I see that the question was not written as clear as it could've been. What i was trying to achieve was filtering out the values in a 1D array that had "". The data populating the array was from a column in a separate worksheet that had empty values (hence the "") and numeric values in it. the code below resolved my issue.
//using .filter()
var itm = tblWK.values;
function filt(itm){
return itm != "";
}
var arry = [];
var sht = [];
var j=0;
var s=0;
arry.values = tblWK.values.filter(filt);
//then to build the display range to show the values:
for (var i=0; i < itm.length-1; i++) {
if (tblWK.values[i][0]){
var arry; //tblWK.values.splice(i,0); -splice did not work, maybe my syntax was wrong?
console.log("this printed: "+tblWK.values[i][0]);
var cl = ('D'+i); //building the range for display
j++; //increasing the range
s=1;//setting the beignning range
var cll = cl.toString();//getRange() must be a string
console.log(cll);//testing the output
}
}
//using the variable from the for loop
var cl = ('D'+s+':D'+j);
var cll = cl.toString();
console.log(cll);//testing the build string
sht = ctx.workbook.worksheets.getItem('Preview').getRange(cll);
sht.values = arry.values; //displays on the preview tab
console.log (arry.values); //testing the output
The question was probably easier said by asking what vanilla javascript functions does office.js support. I found a lot help reading Building Office Add-ins using Office.js by Micheal Zlatkovsky and by reading the MDN documentation as well as the suggested answer posted here.
Regards,
J
I'm not sure what this check is trying to achieve: tblWK.values !== "". .values is a 2D array and won't ever be "".
For Excel, the value "" means that the cell is empty. In other words, if you want to clear a cell, you assign to "". null value assignment results in no-op.
You can just fetch the values form the array that contains null by using for each and can can push the null values into another array.
I've been having a hard time with cross browser compatibility and scrapping the dom.
I've added data analytics tracking to ecommerce transactions in order to grab the product and transaction amount for each purchase.
Initially I was using document.querySelectorAll('#someId')[0].textContent to get the product name and that was working fine for every browser except internet explorer.
It took some time to figure out that it was the .textContent part that was causing ie problems.
Yesterday I changed .textContent to .innerText. From looking inside analytics it seems that the issue has been resolved for ie but now Firefox is failing.
I was hoping to find a solution without writing an if statement to check for the functionality of .textContent or .innerText.
Is there a cross browser solution .getTheText?
If not what would be the best way around this? Is there a simple solution? (I ask given my knowledge and experience with scripting, which is limited)
** added following comments **
If this is my code block:
// build products object
var prods = [];
var brand = document.querySelectorAll('.txtStayRoomLocation');
var name = document.querySelectorAll('.txtStayRoomDescription');
var price = document.querySelectorAll('.txtStayRoomSplashPriceAmount');
for(var i = 0; i < brand.length; i++) {
//set granular vars
var prd = {};
//add to prd object
prd.brand = brand[i].innerText;
prd.name = name[i].innerText;
prd.price = price[i].innerText;
prd.quantity = window.session_context_vars.BookingContext.Booking.ReservationLineItems[i].ReservationCharges.length/2;;
//add to prods array
prods.push(prd);
}
Then if I understand the syntax from the comments and the question linked to in the comment, is this what I should do:
// build products object
var prods = [];
var brand = document.querySelectorAll('.txtStayRoomLocation');
var name = document.querySelectorAll('.txtStayRoomDescription');
var price = document.querySelectorAll('.txtStayRoomSplashPriceAmount');
for(var i = 0; i < brand.length; i++) {
//set granular vars
var prd = {};
//add to prd object
prd.brand = brand[i].textContent || brand[i].innerText;
prd.name = name[i].textContent || name[i].innerText;
prd.price = price[i].textContent || price[i].innerText;
prd.quantity = window.session_context_vars.BookingContext.Booking.ReservationLineItems[i].ReservationCharges.length/2;;
//add to prods array
prods.push(prd);
}
So using or with a double bar || assigns the first non null value?
Re: your edit, not quite. The way to access methods or properties on an object (eg a DOM element) is to use dot notation if you have the name itself, or square brackets in case of variables/expressions (also works with strings, as in obj["propName"], which is equivalent to obj.propName). You can also just test the property against one element and use that from there on:
// build products object
var prods = [];
var brand = document.querySelectorAll('.txtStayRoomLocation');
var name = document.querySelectorAll('.txtStayRoomDescription');
var price = document.querySelectorAll('.txtStayRoomSplashPriceAmount');
for(var i = 0; i < brand.length; i++) {
//set granular vars
var prd = {};
//add to prd object
var txtProp = ("innerText" in brand[i]) ? "innerText" : "textContent"; //added string quotes as per comments
prd.brand = brand[i][txtProp];
prd.name = name[i][txtProp];
prd.price = price[i][txtProp];
prd.quantity = window.session_context_vars.BookingContext.Booking.ReservationLineItems[i].ReservationCharges.length/2;;
//add to prods array
prods.push(prd);
}
Regarding the line:
var txtProp = (innerText in brand[i]) ? innerText : textContent;
The in keyword checks an object to access the property (syntax: var property in object). As for the question notation (I made an error earlier, using ||, the correct thing to use was a :),
var myVar = (prop in object) ? object[prop] : false;
As an expression, it basically evaluates the stuff before the ?, and if it's true, returns the expression before the :, else the one after. So the above is the same as / a shorthand for:
if(prop in object){
var myVar = object[prop];
}
else{
var myVar = false;
}
Since you are checking between two properties only and wanting to assign one or the other, the shortest way would indeed be:
var txtProp = brand[i].innerText || brand[i].textContent;
It would basically test the first property, and if it were false or undefined, it would use the second one. The only reason I (pedantically) avoid using this is because the first test of a || b would fail even if a existed but just had a value of 0, or an empty string (""), or was set to null.
I have to create cart system in my mobile application, i want to store the id and the quantity of products, the id should be the key of my array (for modifying product quantity) , tried to use object instead of array but i get error: undefined is not a function when i try to read my json variable
by JSON.stringify(cart)
My cart code is like this
var cart = [];
var produit = {};
produit['qte'] = $('.'+id_prd).text();
produit['id_produit'] = id_prd;
cart[id_prd] = produit;
window.sessionStorage["cart1"]= JSON.stringify(cart);
return me
{"7":{"qte":"1","id_produit":7},"8":{"qte":"1","id_produit":8}}
when I tried to parse the json string with
var parsed = $.parseJSON(window.sessionStorage["cart1"]);
i get the error 'undefined is not a function'
when triying to read the json with
var i=0;
for (k in parsed) {
var k_data = parsed[k];
k_data.forEach(function(entry) {
alert(entry);
ch+=entry.id_produit;
if(i<parsed.length-1)
ch+= ',';
if(i==parsed.length-1)
ch+=')';
i++;
});
}
Can you clarify me the error cause, and if there's a solution to better read the json
The problem is that you are using k_data.forEach(function(entry) but forEach is for Arrays, and k_data is just a simple javascript object.
Try changing:
k_data.forEach(function(entry){
to this:
$(k_data).each(function(entry){
Even more, if the JSON is always in the same structure you posted, I think the each function is not necessary, maybe this is the way you are looking for:
var i=0;
var ch = "(";
for (k in parsed) {
var k_data = parsed[k];
alert(k_data);
ch+=k_data.id_produit;
ch+= ',';
i++;
}
ch = ch.substring(0, ch.length - 1) + ")";
You shouldn't need jQuery for this. The same JSON object you used to stringify has a parse function:
var parsed = JSON.parse(window.sessionStorage["cart1"]);
If that still breaks, there's probably something wrong with another undefined object.
You can try something like this:
<script type="text/javascript">
var finalArr = new Array();
var dataArr = new Array();
dataArr = window.sessionStorage["cart1"];
if (JSON.parse(dataArr).length > 0) {
for (var i = 0; i < JSON.parse(dataArr).length; i++) {
finalArr.push((JSON.parse(dataArr))[i]);
}
}
</script>
I imported json data into google scripts with:
var doc = Utilities.jsonParse(txt);
I can access most of the objects like such...
var date = doc.data1.dateTime;
var playerName = doc.data1.playerName;
var playerId = doc.data1.playerID;
var teamNumber = doc.data2.personal.team;
A bunch of objects I need to access have numbers as object names...
doc.data2.personal.team.87397394.otherdata
doc.data2.personal.team.87397395.otherdata
doc.data2.personal.team.87397396.otherdata
doc.data2.personal.team.87397397.otherdata
...but when I try to read the data with...
var teamId = doc.data2.personal.team.87397394;
... I get an error "Missing ; before statement."
I tried this...
var teamId = doc.data2.personal.team[87397394];
... and get "teamId undefined" in the log.
I also tied this with the same result...
var teamId = doc.data2.personal.team[+'6803761'];
I can read in the names as strings very easily with "For In", but can't get to the objects themselves. Every example I've found so far uses the brackets so I'm stumped what to try next.
Thank you!
Brian
UPDATE
I used this per your suggestions to get the object name into a variable and using the variable in brackets. No error but var test remains "undefined"...
for(var propertyName in doc.data2.personal.team) {
// propertyName is what you want
// you can get the value like this: myObject[propertyName]
Logger.log (propertyNames);
var test = doc.data2.personal.team[propertyName];
}
The log shows the object names, as expected...
87397394
87397395
87397396
87397397
I'm thinking it's a bug in Google's implementation. Here is an example if anyone wants to verify it. test will return undefined...
function myFunction1() {
var txt = UrlFetchApp.fetch("http://www.hersheydigital.com/replays/replays_1.json").getContentText();
var doc = Utilities.jsonParse(txt);
for(var propertyName in doc.datablock_battle_result.vehicles) {
Logger.log (propertyName);
var test = doc.datablock_battle_result.vehicles[propertyName];
}
}
The problem seems to be in the Utitlies.jsonParse. The following works fine
var txt = UrlFetchApp.fetch("http://www.hersheydigital.com/replays/replays_1.json").getContentText();
var doc = JSON.parse(txt);
for(var propertyName in doc.datablock_battle_result.vehicles) {
var vehicle = doc.datablock_battle_result.vehicles[propertyName];
Logger.log('Vehicle id is ' + propertyName);
Logger.log('Vehicle value is ' + JSON.stringify(vehicle));
break;
}