I would like to get the length of the 'obj' object so that I can do a for-loop with it, here is my code:
var oRequest = new XMLHttpRequest();
var sURL = "/Users/files/Documents/time.json";
oRequest.open("GET",sURL,false);
oRequest.send();
var txt = oRequest.responseText;
var obj = eval ("(" + txt + ")");
My goal is that I would like to output everything in this time.json file to the screen.
Here is what my json file looks like:
{
"employees": [
{ "firstName":"John" , "lastName":"Doe" },
{ "firstName":"Anna" , "lastName":"Smith" },
{ "firstName":"Peter" , "lastName":"Jones" }
]
}
The object you create does not have have a length. I assume you meant employees length and not the obj length
Like this:
Live Demo
var txt = oRequest.responseText;
// eval("var obj = "+txt); // eval is not recommended but here is how
var obj = JSON.parse(txt); // this is better
var emp = obj?obj.employees:[]; // if we have a useful object, get the employees
window.onload=function() {
var empDiv = document.getElementById("empDiv");
for (var i=0;i<emp.length;i++) {
empDiv.innerHTML+=emp[i].firstName + " "+ emp[i].lastName + '<br/>';
}
}
you don't have to get a length in order to do a for loop on an object, based on your object structure you can get data with the following loop:
for(var key in object) {
var o = object[key];
for(var i = 0; i < o.length; i++) {
var user = o[i];
alert(user.firstName);
}
}
Related
Using app scripts I'm trying to extract all the email addresses from email messages and put them in an array. From my console.log messages, I'm getting stuck because it looks like instead of an array I just get a string. i'm not too familiar with javascript. Any help would be great. I'm looking for an array of email address. The methods of message.get() return a string. I want to split out the email address and create a single, unified array.
var ui = SpreadsheetApp.getUi();
function onOpen(e){
ui.createMenu("Gmail Manager").addItem("Get Emails by Label", "getGmailEmails").addToUi();
}
function getGmailEmails(){
var label = GmailApp.getUserLabelByName("MyLabel");
var threads = label.getThreads();
var fullArray = [];
for(var i = threads.length - 1; i >=0; i--){
var messages = threads[i].getMessages();
for (var j = 0; j <messages.length; j++){
var message = messages[j];
if (message.isUnread()){
fullArray.push(extractDetails(message));
}
}
}
console.log("FullArray:"+fullArray);
for(var i=0; i<fullArray.length; i++){
console.log("printing array " + i + ": "+fullArray[i])
}
}
function extractDetails(message){
var dateTime = message.getDate();
var subjectText = message.getSubject();
var senderDetails = message.getFrom();
var ccEmails = message.getCc();
var replyEmail = message.getReplyTo();
var toEmail = message.getTo();
var emailArray = []
var senderArray = senderDetails.split(',');
var ccArray = ccEmails.split(',');
var replyArray = replyEmail.split(',');
var toArray = toEmail.split(',');
for (var i =0 ; i<toArray.length; i++){
console.log("toArray Loop"+ i + " : "+ toArray[i]);
emailArray.push([toArray[i]]);
}
for (var i =0 ; i<ccArray.length; i++){
console.log("ccArray Loop"+ i + " : "+ ccArray[i]);
emailArray.push([ccArray[i]]);
}
console.log("Email Array: "+ emailArray);
var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
activeSheet.appendRow([dateTime, senderDetails, subjectText, ccEmails,replyEmail,toEmail,emailArray]);
return emailArray;
}
I think the problem is just the console output. If you change console.log("Email Array: "+ emailArray); to console.log("Email Array: ", emailArray);, then it shows an array of arrays. You could simplify your extract method as follows:
function extractDetails(message) {
/* ... */
var senderDetails = message.getFrom();
var ccEmails = message.getCc();
var replyEmails = message.getReplyTo();
var toEmails = message.getTo();
let emailArray = [senderDetails, ccEmails, replyEmails, toEmails].reduce(
(array, string) => {
//remove names (like "Name <name#company.com>") and filter empty values
let emails = string
.split(/\s*,\s*/)
.map(e => e.replace(/.*?([^#<\s]+#[^#\s>]+).*?/g, "$1"))
.filter(Boolean);
if(emails.length > 0)
return array.concat(emails)
return array
}, []);
/* ... */
}
I'm just learning javascript and I'm trying to update woocommerce products through GAS.
The issue in question is the following:
I have a variable that parses the response from woocommerce
for (let sku of skuSearch) {
var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&sku=" + sku;
var url = surl
Logger.log(url)
var result = UrlFetchApp.fetch(url, optionsGet);
if (result.getResponseCode() == 200) {
var wooProducts = JSON.parse(result.getContentText());
Logger.log(result.getContentText());
}
Then I have another for to iterate and from a new array that contains id + sku of wooProducts and price from a different variable that takes the updated price from my sheet:
var idLength = wooProducts.length;
Logger.log(idLength);
for (var i = 0; i < idLength; i++) {
var container = [];
Logger.log(i);
container.push({
id: wooProducts[i]["id"],
sku: wooProducts[i]["sku"],
price: data[i]["price"],
});
I can't tell exactly why it doesn't work. I mean the for loop works, it pushes id, sku and price in every loop, it's just that data[i] only provides the first ¿object? instead of looping like wooProducts which add +1 at every loop.
I'll copy 3 loops so it's crystal clear, I'm not sure it's already clear.
Loop 1:
[{"id":1622,"sku":"PD-1000-B","price":8145.9}]
Loop 2:
[{"id":1624,"sku":"PD-1007-A","price":8145.9}]
Loop 3:
[{"id":1625,"sku":"PD-1014","price":8145.9}]
As you can see id+sku change but price doesn't.
For further context, I'll include the data variable that is declaed outside the For:
const data = codigos.map(function(codigos, indice) {
return {
sku: codigos[0],
price: precios[indice][0]
}
})
//** EDIT:
I'm adding the entire code so it makes more sense maybe?
function getDataloopwoo() {
var ck = 'xxx'
var cs = 'xxx'
var website = 'xxx'
var optionsGet =
{
"method": "GET",
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
"muteHttpExceptions": true,
};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PreciosBULK');
var codigos = sheet.getRange("A2:A").getValues();
var precios = sheet.getRange("B2:B").getValues();
var skuSearch = sheet.getRange("A2:A").getValues();
const data = codigos.map(function(codigos, indice) {
return {
sku: codigos[0],
price: precios[indice][0]
}
})
Logger.log(skuSearch)
for (let sku of skuSearch) {
var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&sku=" + sku;
var url = surl
Logger.log(url)
var result = UrlFetchApp.fetch(url, optionsGet);
if (result.getResponseCode() == 200) {
var wooProducts = JSON.parse(result.getContentText());
Logger.log(result.getContentText());
}
var idLength = wooProducts.length;
Logger.log(idLength);
var container = [];
for (var i = 0; i < idLength; i++) {
Logger.log(i);
container.push({
id: wooProducts[i]["id"],
sku: wooProducts[i]["sku"],
price: data[i]["price"],
});
Logger.log(container);
var wooBatch = JSON.stringify(container);
Logger.log(wooBatch);
}
}
}
// FINAL EDIT with "solve":
So I figured it was inefficient to ask by 1 sku at a time, so now I'm asking by the 100, and paginating with a while if and saving id, sku, price to the container array.
I will need now to compare the container array to the array with the updated prices and form a new array with id, sku and updated price, I'm reading up on that right now. The code:
function getDataloopwoo() {
var ck = 'xx'
var cs = 'xx'
var website = 'xx'
var optionsGet =
{
"method": "GET",
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
"muteHttpExceptions": true,
};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('PreciosBULK');
var codigos = sheet.getRange("A2:A").getValues();
var precios = sheet.getRange("B2:B").getValues();
const data = codigos.map(function(codigos, indice) {
return {
sku: codigos[0],
price: precios[indice][0]
}
})
var container = [];
var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&per_page=100";
var url = surl
//Logger.log(url)
var result = UrlFetchApp.fetch(url, optionsGet);
var headers = result.getAllHeaders();
var total_pages = headers['x-wp-totalpages'];
var pages_count = 0;
while (pages_count < total_pages) {
if (result.getResponseCode() == 200) {
var wooProducts = JSON.parse(result.getContentText());
//Logger.log(result.getContentText());
}
for (var i = 0; i < wooProducts.length; i++) {
//Logger.log(i);
container.push({
id: wooProducts[i]["id"],
sku: wooProducts[i]["sku"],
price: wooProducts[i]["price"],
});
Logger.log(container);
}
pages_count++;
if (pages_count < total_pages){
var surl = website + "/wp-json/wc/v3/products?consumer_key=" + ck + "&consumer_secret=" + cs + "&per_page=100" + "&page=" + (pages_count + 1);
var url = surl
var result = UrlFetchApp.fetch(url, optionsGet);
Logger.log(url);
}
}
}
You're reseting the array container in every iteration of the loop:
for (var i = 0; i < idLength; i++) {
var container = []; // <-----------------here
...
container.push({
...
I think the array should be defined outside the loop:
var container = [];
for (var i = 0; i < idLength; i++) {
...
container.push({
...
I want to return from JSON object "mail" for "name" which will be definie by variable C.
var c = "product3"
var text = '{"products":[' +
'{"name":"product1","mail":"jan#mail.com" },' +
'{"name":"product2","mail":"anna#mail.com" },' +
'{"name":"product3","mail":"john#mail.com" }]}';
In this case i want to return product3 john#mail.com
Using ES2015
let productsArr = JSON.parse(text).products;
let result=productsArr.find(product=>product.name===c);
console.log(result.mail);// output john#mail.com
You can do it with ES6's find easily,
var textObj = JSON.parse(text)
var mail = textObj.products.find(itm => itm.name == c).mail
console.log(mail); // "john#mail.com"
DEMO
You can use Array.prototype.filter to return only values of your array which have a name === "product3".
var obj = JSON.parse(text);
var c = "product3";
var requiredProduct = obj.products.filter(function(x) {
return x.name === c;
});
var text = '{"products":[' +
'{"name":"product1","mail":"jan#mail.com" },' +
'{"name":"product2","mail":"anna#mail.com" },' +
'{"name":"product3","mail":"john#mail.com" }]}';
var data = JSON.parse(text);
var data1 = data.products;
console.log(data1[2].name)//get 3rd
console.log(data1[2].mail)//get 3rd
for (var i = 0; i < data1.length; i++) {
console.log(data1[i].name)//iterate here
console.log(data1[i].mail)//iterate here
}
Do it like this
first change var text to
var text = {"products": [
{"name":"product1","mail":"jan#mail.com" },
{"name":"product2","mail":"anna#mail.com" },
{"name":"product3","mail":"john#mail.com" }
]};
then you can access the values as follows
var c = text.products[2].name //returns product3
var email = text.products[2].mail //returns john#mail.com
Hope this helps.
someone can help me here ? How do I add data locally in many columns ?
I have tried but...
Below my code,
I tried to create more var like : "var salary = document.forms.MedList.salary.value; var test = document.forms.MedList.test.value;
localStorage.setItem(name, data, salary, test);
" etc, but It does not work...
I have to change my doShowAll function or something like this ?
function SaveItem() {
var name = document.forms.MedList.name.value;
var data = document.forms.MedList.data.value;
localStorage.setItem(name, data);
doShowAll();
}
function doShowAll() {
if (CheckBrowser()) {
var key = "";
var list = "<tr><th>Nome</th><th>Estoque</th></tr>\n";
var i = 0;
for (i = 0; i <= localStorage.length - 1; i++) {
key = localStorage.key(i);
list += "<tr><td>" + key + "</td>\n<td>"
+ localStorage.getItem(key) + "</td></tr>\n";
}
if (list == "<tr><th>Nome</th><th>Value</th></tr>\n") {
list += "<tr><td><i>empty</i></td>\n<td><i>empty</i></td></tr>\n";
}
document.getElementById('list').innerHTML = list;
} else {
alert('Cannot store Med list as your browser do not support local storage');
}
}
Your best bet is to create an object and store that e.g.
var myObject = {
name: document.forms.MedList.name.value,
data: document.forms.MedList.data.value
}
localStorage.setItem("yourKey", JSON.stringify(myObject));
When you want to grab it out you can do:
var myObject = JSON.parse(localStorage.getItem("yourKey"));
and then access the name and data respectively:
myObject.name
myObject.data
If you wanted to store multiple values under one key, the value can be an array:
e.g.
var myObject = {
name: document.forms.MedList.name.value,
data: document.forms.MedList.data.value
}
var myObject2 = {
name: document.forms.MedList2.name.value,
data: document.forms.MedList2.data.value
}
localStorage.setItem("yourKey", JSON.stringify([myObject, myObject2]));
I have a giving string/url like this
https://example.com/loadcontent?var1=100&var2=:somevar&var3=:morevariables
I need to loop thought each parameter in the url. If the value starts with : this indicated that it is a variable an I will need to change that value dynamically by looking at the corresponding meta attribute that matches that variable.
Here is my code in which loops over an array and sets the value of the parameters.
var baseURL = getBaseURL(url);
var params = getParams(url);
var newParams = $.each(params, function(index, param){
if( param.value.substring(0, 1) == ':'){
var myVar = param.value.substring(1);
param.value = $('meta[name=" + myVar + "']).attr('value');
}
});
var finalURL = baseURL + '?' + jQuery.param( newParams );
function getParams(url){
// This function should return an array of objects. Each object should have 2 properties "value" and "name". The "name" property should be the name of the parameter (ie. var1, var2, var3 .....) and the "value" attribute should contains the value of the parameter (ie. 100, :somevar, :morevariables)
}
function getBaseURL(url){
var cutoff = url.indexOf('?');
if( cutoff > -1){
return url.substring(0, cutoff - 1);
}
return url;
}
I need help converting the parameters of a giving URL to array of object. How can I do this in jQuery?
You dont need jQuery for this one.
function getParams(url) {
var queryString = url.substring(url.indexOf('?') + 1);
var paramsArr = queryString.split('&');
var params = [];
for (var i = 0, len = paramsArr.length; i < len; i++) {
var keyValuePair = paramsArr[i].split('=');
params.push({
name: keyValuePair[0],
value: keyValuePair[1]
});
}
return params;
}
Here is an example using map
var url = 'https://example.com/loadcontent?var1=100&var2=:somevar&var3=:morevariables&test';
function getParamArray(url) {
var queryString = url.substring(url.lastIndexOf("?") + 1);
return queryString.split('&').map(function(sParam) {
var param = sParam.split('=');
return {
name: param[0],
value: decodeURIComponent(param[1])
};
});
}
document.getElementById("output").innerHTML = JSON.stringify(getParamArray(url), null, 2);
<pre id="output"></pre>
With a regular expresion and JSON.parse:
var url = 'https://example.com/loadcontent?var1=100&var2=:somevar&var3=:morevariables';
url = url.replace(/^.*\?/,'');
url = url.replace(/(\w+)=?([\w:]*)/g,'{"name":"$1","value":"$2"}');
url = url.replace(/&/g,',');
var paramsObject = JSON.parse("["+url+"]");
/*
Returns:
Array [{"name":"var1","value":"100"},{"name":"var2","value":":somevar"},{"name":"var3","value":":morevariables"}];
*/
You don't even need JQuery for this.
<script type="text/javascript">
var paramStr = window.location.search;
var params = paramStr.substring(1, paramStr.length).split('&');
var paramList = [];
for (var index=0; index < params.length; index++) {
var param = params[index].split('=');
paramList.push({name: param[0], value: param[1]});
}
</script>
The result:
[Object]0: Object
name: "a"
value: "b"
...
var url=new URLSearchParams(window.location.search);
var params = [];
for(var value of url.keys())
{
params.push({
name: value,
value: url.get(value)
});
}