How to return array - javascript

I am using the below function to load xml and then return the array with values.
But when i call it in another function it gives error "arrXML is undefined".
function readXML() {
// create an array object
var arrXML = new Array();
//create XML DOM object
var docXML = Sys.OleObject("Msxml2.DOMDocument.6.0");
// load xml
docXML.load("C:\\Users\\ankit\\Desktop\\read.xml");
// search nodes with 'config' tag
var Nodes = docXML.selectNodes("//config");
for (i = 0; i < Nodes.length; i++){
var ChildNodes = Nodes.item(i);
arrXML[i] = Nodes(i).childNodes(0).text +":"+Nodes(i).childNodes(1).text;
}
// return array of XML elements
return arrXML;
}
function getvalues() {
log.message(arrXML[1]); // this line gives error
}

arrXML is local to the function readXML because you declared it with the var keyword inside that block. getValues has no idea it exists (because it no longer does).
Your options are to make the variable global (which you should be careful with)
vinu = {}; // vinu is global namespace containing the array
function readXML() {
vinu.arrXML = [];
// ...
return vinu.arrXML; // This might not even be necessary in this case
}
function getvalues() {
log.message(vinu.arrXML[1]);
}
... or to pass the variable to the function when you call it.
function getvalues(arg) {
log.message(arg[arrXML[1]]);
return arg; // This function can't change the original variable, so use the return if need-be
}
// Somewhere that has access to the actual "arrXML"
getvalues(arrXML);
... or use a closure.

Related

Object modified in the function is not being modified outside the function

I'm building a code to parse some JSON details received from the server into a javascript object. The object has many objects inside it.
Then I have another function to create HTML element and apply that object's values (using for - in loop) into HTML tags' "innerHTML".
I have included the code i use below,
// This one is executed on the 'onLoad' event.
function requestDriverListings() {
**//This object stores the received object from server.**
var drivers = {};
// ***This function requests details from the server and the function in the arguments is executed once the details are received.***
sendUserData ({}, "request driver.php", function (request) {
listDrivers(request,drivers); console.log(drivers); displayDrivers(drivers);});
}
This one is the function to create a HTML Element and stores the received data in it and the use JSON.parse() to parse them into a Object.
The driver parameter is the Object passed in the above code.
request parameter has no effect on this problem. (It is the XHR responseText.)
function listDrivers (request,driver) {
var response = document.createElement("html");
response.innerHTML = request;
driver = response.querySelector("#drivers").innerHTML;
var stripComma = driver.lastIndexOf(",");
driver = JSON.parse(driver.substring(0,stripComma) +"}");
}
Here is the displayDrivers function.
drivers Object is passed into driveParsed in the first function.
requestAPage() is a function to request the displaying element from the server. the function in it's arguments is the function to apply the Objects details into the HTML innerHTML.
function displayDrivers (driveParsed) {
var driverElement = document.createElement("div");
driverElement.id = "driverElement";
driverElement.style.display = "none";
document.getElementById("driverContainer").appendChild(driverElement);
requestAPage("Drivers.html", "drivers", "driverElement", function() { selectDrivers();});
var selectDrivers = function () {
for (var x=0; x<=Object.keys(driveParsed).length; x++) {
var driverParsed = driveParsed[x];
setDriversDetails(driveParsed,x);
var element = createAElement( "div", {"margin-top": "10px;"});
element.id = driveParsed.name;
element.className = "container border";
element.innerHTML = driverElement.innerHTML;
document.getElementById("driverContainer").appendChild(element);
}
};
}
================================================================
My problem is this displayDrivers() is not getting the modified drivers Object.
Please help me to solve this problem. Sorry for the long description.
One problem is that inside listDrivers you assign a new value to the driver variable (which is an argument). This means the original variable, drivers, that was passed to the function as second argument, is disconnected from the local function variable driver: they are now two distinct, unrelated objects.
If you want the drivers variable to get a value from calling the function, then let that be the return value of the function, so you would call it like this:
sendUserData ({}, "request driver.php", function (request) {
var drivers = listDrivers(request); // <-----
console.log(drivers);
displayDrivers(drivers);
});
Then the listDrivers function would look like this:
function listDrivers (request) { // <--- only one argument
// declare new variable:
var driver = response.querySelector("#drivers").innerHTML;
// ... rest of your code comes here ...
// ... and finally:
return driver; // <---- return it
}
#trincot beat me to it and his answer is better. I'll leave this up anyway though.
Try doing this in requestDriverListings:
function requestDriverListings() {
var drivers = {};
sendUserData ({}, "request driver.php", function (request) {
var updatedDrivers = listDrivers(request,drivers);
console.log(drivers);
displayDrivers(updatedDrivers);});
}
And this in listDrivers:
function listDrivers (request,driver) {
var response = document.createElement("html");
response.innerHTML = request;
driver = response.querySelector("#drivers").innerHTML;
var stripComma = driver.lastIndexOf(",");
driver = JSON.parse(driver.substring(0,stripComma) +"}");
return driver;
}

Pass Arguments from One Function to Another Without Calling It

I'm trying to get either options or, ideally, dynamicTable passed from initializeTable to the applyTableFilters function and I'm having problems getting the expected values. I'm using List.js to make a table dynamic and I need to pass or recreate the dynamicTable object so I can go ahead and use it to filter the table.
Here is the function that creates the List.js object from the HTML table:
function initializeTable(options) { // initializes table to be dynamic using List.js functions
var dynamicTable = new List("table-content", options);
dynamicTable.on("updated", function (list) { // writes a message to the user if no results are found
if (list.matchingItems.length == 0) {
document.getElementById("no-results").style.display = "block";
}
else {
document.getElementById("no-results").style.display = "none";
}
});
console.log(dynamicTable);
console.log(options);
console.log(arguments.length);
applyTableFilters.bind();
}
I've tried different methods to pass the variables to the function below. I tried .call, applyTableFilters(args), and .apply, but the problem is that I do not want the function to execute from inside here, only when the click event from the button goes off (not shown in these functions).
This is the function I want to pass the object to and proceed to make the filter functions using it:
function applyTableFilters(dynamicTable) {
var form = document.getElementById("filter-form");
//console.log(options);
//var dynamicTable = new List("table-content", options);
console.log(dynamicTable);
var filters = form.querySelectorAll('input[type="checkbox"]:checked');
dynamicTable.filter(function (item) {
console.log(item);
console.log(item._values);
if (item.values().id == 2) {
return true;
}
else {
return false;
}
//var filterStrings = [];
//console.log(filters);
//for (var i = 0; i < filters.length; i++) {
// var filterVal = filters[i].value;
// var filterString = "(" + item.values().column == filterVal + ")"; // filterVal.contains(item.values().column) ||
// filterStrings.push(filterString);
// console.log(filterVal);
// console.log(filterString);
//}
//console.log(filterStrings);
//var filterString = filterStrings.join(" && ");
//console.log(filterString);
//return filterString;
});
}
I've used:
applyTableFilters.bind(this, dynamicTable/options);
applyTableFilters.bind(null, dynamicTable/options);
applyTableFilters.bind(dynamicTable/options);
Switching between the two since I don't need both passed if one ends up working, etc. I always get a mouse event passed in and that's not even the right type of object I'm looking for. How can I get the right object passed? Also all the values in the first function are not empty and are populated as expected so it's not the original variables being undefined or null. Thanks in advance.
From your initializeTable function return a function that wraps the applyTableFilters function with the arguments you want.
Then assign the returned function to a var to be executed later.
function initializeTable(options) {
var dynamicTable = new List("table-content", options);
// other stuff
return function () {
applyTableFilters(dynamicTable)
}
}
// other stuff
var applyTableFiltersPrep = initializeTable(options)
// later, when you want to execute...
applyTableFiltersPrep()
JSFiddle example

Google Apps Script return array values and use them in a javascript function

I am trying return an array and use it in a javascript function, but it doesn't seem to work. My Code.gs is as follows:
function doGet() {
return HtmlService.createHtmlOutputFromFile('test')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function test() {
var locations = [];
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/13q7pIeMUHll6_5xBUpBavaBqALt9fnFnOIO-Hwy_pFc/edit'),
sheet = ss.getActiveSheet(),
range = ss.getRange("D2:D4"),
values = range.getValues();
for (var r=1; r<values.length; r++) {
var row = values[r];
locations.push(row[0]);
}
return locations;
}
The function in my test.html looks as follows:
function hello() {
google.script.run.test();
}
So I want to pass the array and its contents to the hello function in my test.html. How can I make this work?
You need a withSuccessHandler() method chained to your google.script.run:
function hello() {
google.script.run
.withSuccessHandler(injectHTML)
.test();
}
//This captures the returned string from the server side code
function injectHTML(argReturnedArray) {
//To Do - code to inject the HTML
};
Unfortunately, server side .gs code will only return a string. But there's a way to deal with that. Use:
JSON.stringify(yourArray);
Your array is named locations.
return JSON.stringify(locations);
Now you need to convert the JSON string back to an array:
function injectHTML(argReturnedArray) {
/* Put the array into the browsers window object in order to make the
* array named myReturnedArray available to all other functions.
*/
window.myReturnedArray = JSON.parse(argReturnedArray);
//To Do - code to inject the HTML
};
//Get the array in another function
function myOtherFunction() {
//Get the array from the browsers window object
var theArray = window.myReturnedArray;
var i=0, thisElement="";
for (i=0;i<theArray.length;i+=1) {
thisElement = theArray[i];
}
};

Why can I not access an array in factory while I am in a forEach loop with Angular?

I have the following question: Why is it impossible for me to access my array in a forEach loop with Angular. I have made this factory with an array and a function, within the function I have this forEach loop. Outside of the forEach loop I can acces my array with the this keyword. In the forEach loop it gives me a undefined value.
.factory("sendOrder", function () {
return {
paired: [],
send: function () {
var names = document.getElementsByTagName('input');
var ordered = document.getElementsByClassName('ordered');
var i = 0;
console.log(this.paired);//I can access it from here
angular.forEach(names, function (amount, key) {
console.log(this.paired);//Unable to access
i++;
return;
})
}
}
})
Maybe this will help. Angular lets you set the context (this) in forEach. It's one of the arguments. You don't have to set any other variables:
angular.forEach(obj, iterator, [context]);
You've passed in obj and iterator. Just pass in something for context and that will be this in the function.
Because the context of the function changes - this is not what it originally was. The usual fix is to set the original context to a variably (usually called self):
.factory("sendOrder", function () {
return {
paired: [],
send: function () {
var self = this;
var names = document.getElementsByTagName('input');
var ordered = document.getElementsByClassName('ordered');
var i = 0;
console.log(this.paired);//I can access it from here
angular.forEach(names, function (amount, key) {
console.log(self.paired);//should be fine now
i++;
return;
})
}
}
})

Passing a parameter to a function that is added to a List

In below code I'm attempting to add a function test to an Array. The function test contains a parameter param1 :
var param1 = "param1"
var fArr = []
fArr.push(test(param1));
for (var i = 0; i < fArr.length; i++) {
fArr[i](param)
}
function test(param){
console.log('param is '+param)
}
When I run this code I receive error :
Uncaught ReferenceError: param is not defined
How can I pass a parameter to the function that is added to array fArr ?
You're not adding a function to the array. You're calling the function, and adding what it returns to the array. But the function doesn't return anything, so you're pushing undefined onto the array.
What I think you want is:
var param1 = "param1";
var fArr = [];
fArr.push(function() {
test(param1));
});
for (var i = 0; i < fArr.length; i++) {
fArr[i]();
}
function test(param){
console.log('param is '+param);
}
P.S. Get out of the bad habit of omitting ; at the end of statements.
The error is here: fArr[i](param). You never initialized variable param.
Are you sure you do not want to use param1?

Categories