So I have the following issue:
I have a Foundset with a bunch of records, and I'd like to (deep) copy them to a new location, including all values but without the IDs. What's the best way to do this?
If you want to do an deep copy of an foundset you need the follow steps:
Create an empty foundset over retrieveOrCreateFoundset()
iterate over all records of the foundset, that should copied to a new one
get the dataProviders with something like rec.dataprovider()
get the value of each dataprovider on a record rec.value()
be sure that the uuid dataprovider isnt copy to the new Record
set the values to a the new record over the dataproviders
persist the changes
Full code example would be:
var vMobileController = plugins.iBizClientWebService.mobileController();
var vFoundset = vMobileController.currentFoundset();
var vDatabaseManager = vMobileController.dataManager();
var copyFoundSet = vDatabaseManager.retrieveOrCreateFoundset("<datasource>:<label>");
for (var index = 0; index < vFoundset.size(); index++) {
var rec = vFoundset.record(index);
var loc = copyFoundSet.newRecord();
var newRecord = copyFoundSet.record(loc);
var allDataproviders = rec.dataprovider();
for(var i=0;i<allDataproviders.length;i++)
{
var dataProvider = allDataproviders[i];
var dataValue = rec.value(dataProvider);
if(dataProvider != "attribute_id")
{
newRecord.setValue(dataProvider, dataValue);
}
}
}
copyFoundSet.saveData();
Related
So I wrote some code that goes to a book's ID based on a "dictionary" and takes the data from all the sheets in that book after the second sheet. That data is then aggregated into a single array. My question centers around the idea of improving the for loop in the if statement. That is adding the "supplier name" to the front of the subarray that represents a row in the sheet/data. I was told that this is inefficient as the code has to go through each subarray and add a value.
Is there a more efficient way of doing this? I did it this way because I am copying the values of a range which are stored as an array of arrays. So to add data, I have to reaccess the subarrays. Is it possible to add the new data (supplier name) at the same time that the values are being copied? would this be more efficient? It was recommended to use an arrow function, however, I am not familiar with their usage.
function aggregate() {
var combinedData = []
var idArray = {
"suppliername":"id",
};
for (var supplierName in idArray){
var sBook = SpreadsheetApp.openById(idArray[supplierName]);
var sheets = sBook.getSheets();
for (var index = 2; index <sheets.length; index++){
var sheet = sheets[index];
var dataLength = sheet.getRange("E5:E").getValues().filter(String).length;
if(dataLength != 0){
var dataRange = sheet.getRange(5,2,dataLength,14);
var dataValues = dataRange.getValues();
for (row in dataValues) {
dataValues[row].unshift(supplierName);
};
combinedData = combinedData.concat(dataValues);
};
};
};
var dataLength = combinedData.length;
const dSheet = SpreadsheetApp.openById("id").getSheets()[0];
dSheet.getRange(2,1,dSheet.getMaxRows(),dSheet.getMaxColumns()).clearContent();
var dRange = dSheet.getRange(2,1,dataLength,15);
dRange.setValues(combinedData);
};
In your script, how about the following modification?
From:
for (row in dataValues) {
dataValues[row].unshift(supplierName);
};
combinedData = combinedData.concat(dataValues);
To:
combinedData = combinedData.concat(dataValues.map(e => [supplierName].concat(e)));
or
combinedData = [...combinedData, ...dataValues.map(e => [supplierName, ...e])];
References:
map()
Spread syntax
I want to get and store id from idArray to use each id indvidual
I tried to store in session storage but it return the last element
success: function (data) {
const myText = "";
const addressArray = [];
const titleArray = [];
const typeArray = [];
const idArray = [];
data.map((user) => {
addressArray.push(user.address);
titleArray.push(user.title);
typeArray.push(user.jtype);
idArray.push(user.id);
});
container.innerHTML = "";
for (let i = 0; i <= 3; i++) {
let clone = row.cloneNode(true);
container.appendChild(clone);
container.firstChild.innerHTML = "";
jobtitle.innerHTML = data[i].title;
jbtype.innerHTML= typeArray[i];
jbaddress.innerHTML= addressArray[i];
sessionStorage.setItem('jobid',idArray[i]);
}
}
The issue I can see is , since the key is always same , it is overriding the value of the same key.
You can instead do something like
sessionStorage.setItem("jobid-"+i,idArray[i]);
This should solve the problem for sure.
It returns the last value because you are using the same key to store each value. Try using a different key for each or alternately, create an array of ids using map function and store the array in session with the key 'jobid'.
You can serialize and store it in session as follows:
sessionStorage.setItem('jobid', JSON.stringify(idArray));
To read the same back out you can use code like
JSON.parse(sessionStorage.getItem('jobid'));
I read couple posts about the closure in loop but still not really get it how to apply to my situation.
I have three feed urls defined in HTML and using JavaScript promise to return the response when it's ready without blocking the UI. I am able to get two blog entries data per feed url. Now, each returned blog entry has its published date and I would like to sort them from latest to oldest. However, I keep getting the last value when I pushed the object to array. I know this is something to do with closure and since I'm not familiar with closure, I have difficulty to solve this problem. Any help is great appreciated!
var itemArray = [];
var entryObj = {};
promise.then(function (response) {
var parser = new DOMParser();
xml = parser.parseFromString(response, "text/xml");
var items = xml.getElementsByTagName("item");
for (var x = 0; x < items.length && x < limits; x++) {
title = items[x].getElementsByTagName("title")[0].innerHTML;
link = items[x].getElementsByTagName("link")[0].innerHTML;
pubDate = items[x].getElementsByTagName("pubDate")[0].innerHTML;
creator = items[x].getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", "creator")[0].innerHTML;
entryObj.title = title;
entryObj.link = link;
entryObj.pubDate = pubDate;
entryObj.creator = creator;
itemArray.push(entryObj);
// output: all 6 objects contain last value
console.log(itemArray);
}
});
In short : Move the object creation inside the loop.
It's nothing to do with closure. The issue is, you are pushing the same object.
You need a new object to be pushed. So create the object inside the for loop. So that every time you get a new object and it gets pushed to the array.
Code-
var itemArray = [];
promise.then(function (response) {
var parser = new DOMParser();
xml = parser.parseFromString(response, "text/xml");
var items = xml.getElementsByTagName("item");
for (var x = 0; x < items.length && x < limits; x++) {
var entryObj = {};
title = items[x].getElementsByTagName("title")[0].innerHTML;
link = items[x].getElementsByTagName("link")[0].innerHTML;
pubDate = items[x].getElementsByTagName("pubDate")[0].innerHTML;
creator = items[x].getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", "creator")[0].innerHTML;
entryObj.title = title;
entryObj.link = link;
entryObj.pubDate = pubDate;
entryObj.creator = creator;
itemArray.push(entryObj);
// output: Now all values are unique
console.log(itemArray);
}
});
Move var entryObj = {}; into your for loop.
I am trying to parse forex values (all of them) for http://indicador.eof.cl/rss XML feed into a Gooogle Sites trough Google Apps Script.
The script as follow>
function doGet(){
var response = UrlFetchApp.fetch("http://indicador.eof.cl/rss").getContentText();
var parsedResponse = Xml.parse(response, false);
var root = parsedResponse.getElement();
var entries = root.getElement('channel').getElements("item");
for (var i=0; i<entries.length; i++) {
var e = entries[i];
var title = e.getElement("title").getText();
var description = e.getElement("description").getText();
}
var app = UiApp.createApplication();
var TopVar = app.createHorizontalPanel();
TopVar.add(app.createLabel(title).setStyleAttribute("fontSize","12px"));
TopVar.add(app.createLabel(description).setStyleAttribute("fontSize","12px"));
app.add(TopVar);
return app;
}
The issue is the code just bring me the first value no all of them, what i am forgetting?
Best Regards,
Try to move TopVar.add(...); lines inside for loop :
var app = UiApp.createApplication();
var TopVar = app.createHorizontalPanel();
for (var i=0; i<entries.length; i++) {
var e = entries[i];
var title = e.getElement("title").getText();
var description = e.getElement("description").getText();
TopVar.add(app.createLabel(title).setStyleAttribute("fontSize","12px"));
TopVar.add(app.createLabel(description).setStyleAttribute("fontSize","12px"));
}
Actually, I know nothing about google-apps-script. But your current code logic seems a bit off. It doesn't make use of values of local variables declare inside for loop (e, title, and description). Value of those variables changed in every iteration without any code using it.
This is probably a simple problem but I need to create the JavaScript equivalent to N instances of a 'class' whose state must be totally separate.
like:
var car = new Car('Ford');
var car = new Car('Toyota');
How can I achieve this?
You can use an array object to store them:
var cars = [];
cars.push(new Car('Ford'));
cars.push(new Car('Toyota'));
cars[0].beep();
You can iterate over all the stored instances using a for loop:
for (var i = 0; i < cars.length; i++) {
var car = cars[i];
car.beep();
}
It if very difficult to see what the problem is here.
From your code snippet I can see the only problem that you may have in creating new instances is that you'r giving it a the same name.
Give it some other var name:
var ford = new Car('Ford');
var toyota = new Car('Toyota');
Otherwise if you have an array of different makes and want to convert it into an array of car objects you can do this:
var types = ["Ford", "Toyota", "VW", "renault"];
var cars = {};
for (var i = 0; i != types.length ; i++)
cars[types[i]] = new Car(types[i]);
You can access these cars like this:
var ford = cars.Ford;
or like this:
var ford = cars["Ford"];