Passing variables through parameters in Javascript - javascript

Here I have a block of code that I've been debugging over Firebug. I want to know how I can pass my parameter foo into the function getHoliday(param,param,param). Here is the block of code from my XMLHttpRequest.
if (XMLHttpRequestObject.readyState==4 && XMLHttpRequestObject.status == 200)
{
var pp = null
var dd = null
var xmlResponse = XMLHttpRequestObject.responseXML;
var foo = new Array();
foo = parseXML(xmlResponse);
getHoliday(pp,dd,foo);
}
The first two parameters of getHoliday are un-used until later in the process. I want to first load getHoliday with data from the array foo so in the future I can use foo as shown below. As soon as my break point arrives at getHoliday, the script stops so I believe it's the parameters that are wrong. I want to point out, pp and dd are nothing, just place holders for empty undefined parameter.
function getHoliday(monthSelected,theday,names)
{
var HolidayName = new Array();
var holiday = ""
HolidayName = names;
monthSelected = monthSelected + 1;
for(var index = 0; HolidayName.length >= index; index++)
{
if(HolidayName[index] == monthSelected && HolidayName[index+1] == theday)
{
holiday = HolidayName[index+2]
}
}
return holiday
}
As soon as my gets down here, names array that I just passed becomes undefined. Why? Below is how HolidayName array should look.
HolidayName = new Array(2,4,"Party--12:00",2,22,"Eventalist Launch--6:00",2,18,"Play Day--12:00",3,17,"Play Day--12:00"););
When alerting foo the result is:
2,4,"Party--12:00",2,22,"Eventalist Launch--6:00",2,18,"Play Day--12:00",3,17,"Play Day--12:00"
Here is parseXML
function parseXML(xmlData)
{
var aOutput=document.getElementById("testing2");
var events = xmlData.getElementsByTagName('year').length;
for(var i=0;i< events;i++)
{
var eYear = xmlData.getElementsByTagName('year')[i].firstChild.nodeValue;
var eMonth = xmlData.getElementsByTagName('month')[i].firstChild.nodeValue;
var eDay = xmlData.getElementsByTagName('day')[i].firstChild.nodeValue;
var eHour = xmlData.getElementsByTagName('hours')[i].firstChild.nodeValue;
var eMinute = xmlData.getElementsByTagName('minutes')[i].firstChild.nodeValue;
var eTitle = xmlData.getElementsByTagName('title')[i].firstChild.nodeValue;
var holiStr = '"' + eTitle + "--" + eHour +":"+ eMinute + '"';
setup.push(eMonth,eDay, holiStr);
}
return setup;
}

Given the information you have provided, best guess: do you have var foo lower in the code? Javascript does not have block level scoping and these get hoisted to the top of functions and var foo lower could alter your foo value.

Related

Faster way to collect data from JSON than looping in spreadsheet

I am learning Javascript and this is my first time working with Google Sheets Apps Script. What I am doing is taking a large JSON file and importing it into my sheet. After that I am populating a few hundred properties based on the key:value found in the JSON.
This is how it kinda works right now:
Go to first column and first row of my sheet.
Get the name (property name).
Search the JSON for the key and then grab the value.
Update a neighbor cell with the value found in the JSON.
Right now it all works the only issue is it seems to be pretty slow. It takes about .5-1 second per lookup and when I have 200+ properties it just seems slow. This might just be a limitation or it might be my logic.
My sheet can be found here: https://docs.google.com/spreadsheets/d/1tt3eh1RjL_CbUIaPzj10DbocgyDC0iNRIba2B4YTGgg/edit#gid=0
My function that does everything:
function parse() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange(2,1);
var range1 = sheet.getRange("A2");
var cell = range.getCell(1, 1);
var event_line = cell.getValue();
var tmp = event_line.split(". ");
var col_number = tmp[0];
var event_name = tmp[1];
event_json = get_json_from_cell(col_number);
const obj = JSON.parse(event_json);
var traits = obj.context.traits;
var properties = obj.properties;
//Get the range for the section where properties are
var traits_range = sheet.getRange("contextTraits");
var allprop = sheet.getRange("testAll");
var alllen = allprop.getNumRows();
var length = traits_range.getNumRows();
for (var i = 1; i < length; i++) {
var cell = traits_range.getCell(i, 1);
var req = traits_range.getCell(i, 4).getValue();
var trait = cell.getValue();
var result = traits[trait];
var result_cell = traits_range.getCell(i, 3);
if (result == undefined) {
if (req == "y"){
result = "MISSING REQ";
result_cell.setBackground("red");
} else {
result = "MISSING";
result_cell.setBackground("green");
}
} else {
result_cell.setBackground("blue");
}
result_cell.setValue(result);
Logger.log(result);
}
for (var i = 1; i < alllen; i++) {
var cell = allprop.getCell(i,1);
var req = allprop.getCell(i, 4).getValue();
var prop = cell.getValue();
var result = properties[prop];
var result_cell = allprop.getCell(i, 3);
if (result == undefined) {
if (req == "y"){
result = "MISSING REQ";
result_cell.setBackground("red");
} else {
result = "MISSING";
result_cell.setBackground("green");
}
} else {
result_cell.setBackground("blue");
}
result_cell.setValue(result);
}
Logger.log(result);
}

How do I make the right conditions for the url based on the value of a variable? (javascript)

My script javascript like this :
<script>
var url = 'http://my-app.test/item';
var sessionBrand = 'honda';
var sessionModel = 'jazz';
var sessionCategory = 'velg';
var sessionKeyword = 'RS 175/60 R 15';
if(sessionBrand)
var brand = '?brand='+sessionBrand;
else
var brand = '';
if(sessionModel)
var model = '&model='+sessionModel;
else
var model = '';
if(sessionCategory)
var category = '&category='+sessionCategory;
else
var category = '';
if(sessionKeyword)
var keyword = '&keyword='+this.sessionKeyword;
else
var keyword = '';
var newUrl = url+brand+model+category+keyword;
console.log(newUrl);
</script>
The result of console.log like this :
http://my-app.test/item?brand=honda&model=jazz&category=velg&keyword=RS 175/60 R 15
var sessionBrand, sessionModel, sessionCategory and sessionKeyword is dynamic. It can change. It can be null or it can have value
I have a problem
For example the case like this :
var sessionBrand = '';
var sessionModel = '';
var sessionCategory = '';
var sessionKeyword = 'RS 175/60 R 15';
The url to be like this :
http://my-app.test/item&keyword=RS 175/60 R 15
Should the url like this :
http://my-app.test/item?keyword=RS 175/60 R 15
I'm still confused to make the condition
How can I solve this problem?
Just use the array for params and then join them with & separator. For example:
var url = 'http://my-app.test/item';
var sessionBrand = 'honda';
var sessionModel = 'jazz';
var sessionCategory = 'velg';
var sessionKeyword = 'RS 175/60 R 15';
var params = [];
if (sessionBrand) {
params.push('brand=' + sessionBrand);
}
if (sessionModel) {
params.push('model=' + sessionModel);
}
if(sessionCategory) {
params.push('category=' + sessionCategory);
}
if(sessionKeyword) {
params.push('category=' + sessionCategory);
}
var newUrl = url + '?' + params.join('&');
console.log(newUrl);
The problem with your code is that it is prefacing all query parameters with a & - except for the sessionBrand. What you need in a URL is for the first parameter to start with a ?, and all others with a &. As you saw, your code doesn't do this when there is no sessionBrand.
There are number of ways to fix this. Probably the neatest I can think of is to assemble the various parts as you are, but without any prefixes - then join them all together at the end. Like this (I just saw Viktor's solution, it's exactly the same idea, but neater because he rewrote more of your earlier code):
if(sessionBrand)
var brand = 'brand='+sessionBrand;
else
var brand = '';
if(sessionModel)
var model = 'model='+sessionModel;
else
var model = '';
if(sessionCategory)
var category = 'category='+sessionCategory;
else
var category = '';
if(sessionKeyword)
var keyword = 'keyword='+this.sessionKeyword;
else
var keyword = '';
var queryString = '?' + [sessionBrand, sessionModel, sessionCategory, sessionKeyword].filter(function(str) {
return str.length > 0;
}).join("&");
var newUrl = url+queryString;

How to empty an Array in a Script

I have a script that uses AJAX/PHP/SQL to query data and pushes it into an array with a bunch of IF's statements. The changeData function is called every 6 seconds. The first query I return I have 6 arrays. The second time i send a request, my push array(IsVacant1) is double and went to 12. after a while, I have over 500 arrays going into my .each statement.
How do I 'clear' this every time I make a request so that I am not adding arrays? Any help is most appreciated.
function changeData() {
isPaused = true;
var mydata0 = null;
$.post('php/ProductionChange.php', {
'WC': cc
}, function(data) { // This is Where I use an AJAX call into a php file.
mydata0 = data; // This takes the array from the call and puts it into a variable
var pa = JSON.parse(mydata0); // This parses the data into arrays and elements
var temp = {};
var bayData = '';
if (pa != null) {
for (var i = 0; i <= pa.length - 1; i++) {
var job = pa[i][0];
var shipdate = pa[i][1];
var status = pa[i][2];
var name = pa[i][3];
var EnclLoc = pa[i][13];
var Enclsize = pa[i][14];
var backpan = pa[i][15];
var percentCom = pa[i][16];
var IsVisible = pa[i][17];
var png = pa[i][18];
var WorkC = pa[i][20];
baydata = 'bayData' + i + '';
temp = {
job, shipdate, name, EnclLoc, Enclsize, backpan, percentCom, IsVisible, png, WorkC, status
};
isVacant1.push({
baydata: temp
});
}
} else {
ii = 1;
//alert("There are no more job numbers in this bay location. Thank you. ");
}
$.each(isVacant1, function(key, value) {
var job = value.baydata.job;
var ship = value.baydata.shipdate;
var name = value.baydata.name;
var encl = value.baydata.EnclLoc;
var EnclSize = value.baydata.EnclLoc;
var percentCom = value.baydata.percentCom;
var backpan = value.baydata.backpan;
var PngLogo = value.baydata.png;
var IsVisible = value.baydata.IsVisible;
var WorkC = value.baydata.WorkC;
var status = value.baydata.status;
var p = WorkC;
WorkC = (WorkC < 10) ? ("0" + WorkC) : WorkC;
//// remember if the encl location matches the workcell cell then do stuff based on that....... hint encl image not hiding becase of duplicate 17s
if (((encl == p) || (backpan == p)) && job != 123) {
$('#WC' + p).show();
document.getElementById("bayData" + p).innerHTML = name + ' ' + ship; // Work Cell Name and Ship Date
document.getElementById("bayData" + p + "a").innerHTML = job; // Work cell Job Number
document.getElementById("percentCom" + p).innerHTML = percentCom + '%'; // Work Cell Percent Complete
} else {
$('#WC' + p).hide();
From your question it looks like you want to clear the isVacant1 array.
In your ajax callback just put isVacant1 = []; as the first line. Like this
function(data) { // This is Where I use an AJAX call into a php file.
isVacant1 = [];
mydata0 = data; // This takes the array from the call and puts it into a variable
var pa = JSON.parse(mydata0); // This parses the data into arrays and elements
var temp = {};
var bayData = '';
..................
From your code it's not clear how you are declaring/initializing isVacant1 so i have suggested isVacant1 = [] otherwise you can also use isVacant1.length = 0.
You can also take a look here How do I empty an array in JavaScript?

How to return array from JavaScript function that retrieves data from text file?

I am building a Windows 8 Store app with HTML/CSS/JavaScript. I am reading in data from a text file through a function, and then putting that data into an array. I am trying to return the array through the function, but it is not working. Any help would be greatly appreciated. I've attached my code snippet.
// Load user data
var DefineUserData = function LoadUserData() {
return Windows.Storage.ApplicationData.current.localFolder.getFileAsync(loadfile).done(function (UserFile) {
return Windows.Storage.FileIO.readTextAsync(UserFile).done(function (fileResult) {
var userdata = new Object();
var dataobject = {};
var innercount;
var outercount;
var fileResultByLines = fileResult.split("\n");
for (outercount = 0; outercount <= (fileResultByLines.length - 2) ; outercount++) {
var tempArray = fileResultByLines[outercount].split(",");
dataobject.metrictitle = tempArray[0];
dataobject.numinputs = tempArray[1];
dataobject.inputs = new Array();
for (innercount = 0; innercount <= parseInt(dataobject.numinputs) ; innercount++) {
dataobject.inputs[innercount] = tempArray[innercount + 2];
}
userdata[outercount] = dataobject;
}
return userdata;
});
},
function (errorResult) {
document.getElementById("resbutton1").innerText = errorResult;
})
}
Your DefineUserData function is returning a Promise, not a value. Additionally done functions don't return anything. Instead you'll need to use then functions instead of done functions in DefineUserData and then handle add a done function (or then) to the code that calls this function.
Also, You can make your promises easier to read, and easier to work with by chaining then functions instead of nesting them.
Currently on Win7 at the office so I can't test this, but try something similar to this pseudo-code. Note then functions instead of done. The last then returns your data. Sample snippet afterwards to illustrate calling this and handling the result.
// modified version of yours
var DefineUserData = function LoadUserData() {
return Windows.Storage.ApplicationData.current.localFolder
.getFileAsync(loadfile)
.then(function (UserFile) {
return Windows.Storage.FileIO.readTextAsync(UserFile);
}).then(function (fileResult) {
var userdata = new Object();
var dataobject = {};
var innercount;
var outercount;
var fileResultByLines = fileResult.split("\n");
for (outercount = 0; outercount <= (fileResultByLines.length - 2) ; outercount++) {
var tempArray = fileResultByLines[outercount].split(",");
dataobject.metrictitle = tempArray[0];
dataobject.numinputs = tempArray[1];
dataobject.inputs = new Array();
for (innercount = 0; innercount <= parseInt(dataobject.numinputs) ; innercount++) {
dataobject.inputs[innercount] = tempArray[innercount + 2];
}
userdata[outercount] = dataobject;
}
return userdata;
},
function (errorResult) {
document.getElementById("resbutton1").innerText = errorResult;
});
}
// some other code...
DefineUserData.done(function (userdata) {
// do something
});

How to access an object from a callback function?

I feel bad because it is very likely this has already been answered and I am just not using the right search terms. I am very new to asynchronous JavaScript. So, I will lead with an apology. If someone could even just help me get the right search terms I would most appreciate it.
I am trying to use the Google feeds api. I have it working when I follow the stock example as laid out in the hello world section. I am trying to make something that is a little more extensible so that I can use it in several places. So I created an object...
function AlertRSS(num, url, div, date) {
this.num = typeof num !== 'undefined' ? num : 5;
this.url = typeof url !== 'undefined' ? url : 'http://arstechnica.com/author/caseyjohnston/feed/';
this.sel = typeof sel !== 'undefined' ? sel : '#alert';
this.date = typeof date !== 'undefined' ? date : this.getYesterday();
}
I then try to call the object inside of the method...
AlertRSS.prototype.displayFeed = function() {
var retval = null;
var feed = new google.feeds.Feed(this.url);
feed.load(function(result) {
var tmp = this;
if (!result.error) {
for ( var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
console.log(sel + ' <h2>' + entry.title + '</h2><br />');
$(tmp.sel).append('<h2>' + entry.title + '</h2><br />');
}
}
});
};
However, it seems like I am not able to access the properties from the object. I keep getting a Uncaught ReferenceError: sel is not defined in the console.
I think the issue is related to scope, but at this point I feel a little out of my depth. Any help would be most appreciated.
Update
For a first post this was a travesty. I had numerous mistakes in my code. Both responses were correct. However, in case another poor newb like me sees this question, I wanted to put working code out there.
The issue turned out to be placement of the var tmp = this; line. It needs to be placed outside of the internal callback function to work. As per Tomasz Nurkiewicz suggestion, I also changed var tmp to var that. Working code is as follows:
function AlertRSS(num, url, sel, date) {
this.num = typeof num !== 'undefined' ? num : 5;
this.url = typeof url !== 'undefined' ? url : 'http://arstechnica.com/author/caseyjohnston/feed/';
this.sel = typeof sel !== 'undefined' ? sel : '#alert';
this.date = typeof date !== 'undefined' ? date : this.getYesterday();
}
AlertRSS.prototype.displayFeed = function() {
var feed = new google.feeds.Feed(this.url);
var that = this;
feed.load(function(result) {
if (!result.error) {
for ( var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
console.log(that.sel + ' <h2>' + entry.title + '</h2><br />');
$(that.sel).append('<h2>' + entry.title + '</h2><br />');
}
}
});
};
You are correctly creating tmp variable to capture this (note that typically it is called that in this context). You are even correctly using this reference here: tmp.sel. However you forgot to use it in line before that:
console.log(sel + ' <h2>' + entry.title + '</h2><br />');
Change to:
console.log(tmp.sel + //...
and you'll be fine.
Your function params ask for div not sel.

Categories

Resources