use .removeFromThreads in more than 100 threads inside a google app script - google-apps-script

i have a script that removes every thread within a label and all sublabels.This was workng fine, but recently i got an error that says that the operation childrens[i].removeFromThreads(threads); can not be applied to more that 100 threads... How can i fix this?
function removingThreadsfromLabel() {
var parentlabelstring = 'THELabel';
var parentlabel = GmailApp.getUserLabelByName(parentlabelstring);
var childrens = children(parentlabel);
for (var i = 0; i < childrens.length; i++){
var threads = childrens[i].getThreads();
childrens[i].removeFromThreads(threads);
}
}
function children(parent) {
var name = parent.getName() + '/';
return GmailApp.getUserLabels().filter(function(label) {
return label.getName().slice(0, name.length) == name;
});
}
For now i have done the following, but it is not optimal...
function removingThreadsfromLabel() {
var parentlabelstring = 'THELabel';
var parentlabel = GmailApp.getUserLabelByName(parentlabelstring);
var childrens = children(parentlabel);
for (var i = 0; i < childrens.length; i++){
var threads = childrens[i].getThreads();
Logger.log(threads.length);
while (threads.length>100){
childrens[i].removeFromThread(threads[0]);
var threads = childrens[i].getThreads();
}
childrens[i].removeFromThreads(threads);
}
}
Regards,

Ok, i figure out how to do it in batch, so it is better that my first solution:
function removingThreadsfromLabel() {
var batchSize = 100;
var parentlabelstring = 'THELabel';
var parentlabel = GmailApp.getUserLabelByName(parentlabelstring);
var childrens = children(parentlabel);
for (var i = 0; i < childrens.length; i++){
var threads = childrens[i].getThreads();
Logger.log(threads.length);
for (var j = 0; j < threads.length; j+=batchSize) {
childrens[i].removeFromThreads(threads.slice(j, j+batchSize));
}
var threads = childrens[i].getThreads();
childrens[i].removeFromThreads(threads);
}

Related

Retrieving google form response data

I have a google form, where I need to use item ID and get all the response for that Item.
I have the below script which will timeout if the form has more than 3000 responses, as its inefficient
How Do I optimize it to retrieve all the items in a short span of time
fO.items = ["ItemID1","ItemID2","ItemID3"...];
for (var i = 0; i < responses.length; i++) {
var response = responses[i];
var otherItems = '';
var flag = true;
for (var j = 0; j < fO.items.length; j++) {
var item = form.getItemById(parseInt(fO.items[j]));
if (response.getResponseForItem(item))
var otherItems = otherItems + "\t" + response.getResponseForItem(item).getResponse();
else
flag = false;
}
if (flag) {
columnData.push(otherItems);
responseIds.push(response.getId());
}
}
Currently, your code is getting the item object with the following line:
var item = form.getItemById(parseInt(fO.items[j]));
So, that line of code is reading the Form many times.
You could try getting the item objects once, putting them into a JSON object, and then retrieving them as needed.
I haven't tested this code, and I don't know if it will work, or if it will be faster if it does work. But thought I'd share the idea.
function getSomeAnswers() {
var form,flag,i,item,itemID,itemList,itemsObject,
k,L,L_items,otherItems,responses,response,thisAnswer;
itemList = ["ItemID1","ItemID2","ItemID3"];
form = FormApp.getActiveForm();
responses = FormApp.getActiveForm().getResponses();
itemsObject = {};
L_items = itemList.length;
for (i = 0; i < L; i++) {//Compile a list of item objects
itemID = parseInt(itemList[i]);
itemsObject[itemID] = form.getItemById(itemID);
}
L = responses.length;
for (i = 0; i < L; i++) {
response = responses[i];
otherItems = '';
flag = true;
for (k in itemsObject) {//Loop through every item to get
item = itemsObject[k];
thisAnswer = response.getResponseForItem(item);
Logger.log(thisAnswer)
if (thisAnswer)
otherItems = otherItems + "\t" + response.getResponseForItem(item).getResponse();
else
flag = false;
}
/*
if (flag) {
columnData.push(otherItems);
responseIds.push(response.getId());
}
*/
}
}

TypeError: Cannot call method "getThreads" of null

I'm getting a "cannot call method" error on this, when I'm pretty sure it should be fine...
function cleanUp() {
var delayDays = 2
var maxDate = new Date();
maxDate.setDate(maxDate.getDate()-delayDays);
var label = GmailApp.getUserLabelByName("Inbox");
var threads = label.getThreads(0, 50);
for (var i = 0; i < threads.length; i++) {
if (threads[i].getLastMessageDate()<maxDate)
{
threads[i].moveToTrash();
}
}
}
What am I doing wrong?
Instead of using
var label = GmailApp.getUserLabelByName("Inbox");
var threads = label.getThreads(0, 50);
Try using
var threads = GmailApp.getInboxThreads(0, 50);

dynamically add children to component, then dynamically manipulate them?

i dont know why this doesnt work. i have a tabnavigator which i dynamically add a navigatecontainer to which has a textarea dynamically added to the nav container. the id's of both have the same stringname as the chatguys[c][0].
it gives errors saying 'TypeError: Error #1034: Type Coercion failed: cannot convert spark.skins.spark::SkinnableContainerSkin#9737851 to spark.components.TextArea." at runtime. wut do?
any help would be greatly appreciated, thank you :(
var idx:uint;
const len:uint = navigate.numChildren;
var alreadyexists:Boolean = false;
for (idx = 0; idx < len; idx++) {
//var check:spark.components.TextArea = navigate.getElementAt(idx) as spark.components.TextArea;
//var check:Tab = navigate.getTabAt(idx) as Tab;
var check:NavigatorContent = navigate.getChildAt(idx) as NavigatorContent;
// var check = navigate.getElementAt(idx);
//elmt.selected = tgBtn.selected;
if (check.label == evt.username)
{// trace(navigate.getChildAt(idx).label);
var c:uint;
const p:uint = chatguys.length;
for (c = 0; c < p; c++){
if(chatguys[c][0] == evt.username){
spark.components.TextArea(DisplayObjectContainer(navigate.getChildAt(idx)).getChildAt(chatguys[c][0])).textFlow=TextConverter.importToFlow(chatguys[c][1], TextConverter.TEXT_FIELD_HTML_FORMAT);
}}
b here ill show you the second half which works fine, but maybe i need to do it differently to get waht i need done ?
var chats:Array = [];
var chatguys:Array = [];
public function userlist_click() :void{
var windowname:Object =users_lst.selectedItem;
var idx:uint;
const len:uint = navigate.numChildren;
trace(navigate.numChildren);
var alreadyexists:Boolean = false;
for (idx = 0; idx < len; idx++) {
var check:NavigatorContent = navigate.getChildAt(idx) as NavigatorContent;
if (check.label == windowname.name)
{
alreadyexists = true;
}
}
if (alreadyexists == false)
{
chats[windowname.name] = new spark.components.TextArea();
chats[windowname.name].x = 10;
chats[windowname.name].y= 32;
chats[windowname.name].width= 517.19696 ;
chats[windowname.name].height= 343.18182;
chats[windowname.name].scroller
chats[windowname.name].x="9";
chats[windowname.name].y="2";
chats[windowname.name].width="517.19696";
chats[windowname.name].height="343.18182";
chats[windowname.name].setStyle("skinClass", spark.skins.spark.TextAreaSkin);
//textArea.skinClass= "spark.skins.spark.TextAreaSkin";
chats[windowname.name].text="ffg";
chats[windowname.name].setStyle("verticalScrollPolicy", ScrollPolicy.ON);
var match = new Array();
match.push(windowname.name);
match.push('bob');
chatguys.push(match);
for (var i in chatguys){
if (chatguys[i][0] == windowname.name){
chats[windowname.name].textFlow=TextConverter.importToFlow(chatguys[i][1], TextConverter.TEXT_FIELD_HTML_FORMAT);
}}
chats[windowname.name].id = windowname.name;
trace(chats[windowname.name]);
var messagebox:NavigatorContent = new NavigatorContent;
messagebox.percentWidth= 100;
messagebox.percentHeight= 100;
messagebox.label = chats[windowname.name];
messagebox.id = chats[windowname.name];
trace(messagebox.label);
messagebox.addElement(chats[windowname.name]);
navigate.addChild(messagebox); }}

Odd numbers of object extraction from an array

I'm trying to get 2 objects at a time form the array for now. but soon I will be using odd number of length and splicing items.
This works out perfectly so far with Even numbers in the Array, but I am not sure how to make it work with odd numbers. The way I think it may work is ask it to check the objects coming up next and if it is less than 2 than change the counters to 1. but I am not even sure how to put that in code specifically. I posted my code so far be
import flash.events.MouseEvent;
import flash.net.Socket;
var socket_Array_current_position = 0;
var socket_counter = 2;
var socket_Array: Array = new Array ();
socket_Array.push(socket_one, socket_two,socket_three, socket_four, socket_five, socket_six);
go_next_left.addEventListener(MouseEvent.CLICK, go_left);
go_next_right.addEventListener(MouseEvent.CLICK, go_right);
function go_left(going_left:MouseEvent)
{
if (socket_Array_current_position > 0)
{
socket_remove();
socket_Array_current_position -= socket_counter;
socket_x_position = 125;
socket_display();
}
}
function go_right(going_right:MouseEvent)
{
if (socket_Array_current_position < socket_Array.length-socket_counter)
{
socket_remove();
socket_Array_current_position += socket_counter;
socket_x_position = 125;
socket_display();
}
}
socket_display();
function socket_display()
{
var s = 0;
for (s; s < socket_counter; s++)
{
addChild(socket_Array[socket_Array_current_position + s]);
socket_Array[socket_Array_current_position + s].x = socket_x_position;
socket_Array[socket_Array_current_position + s].y = socket_y_position;
//socket_Array[s].addEventListener(MouseEvent.CLICK, picked);
socket_x_position = socket_x_position + 275;
}
}
function socket_remove()
{
var s = 0;
for (s; s < socket_counter; s++)
{
removeChild(socket_Array[socket_Array_current_position+s]);
}
}
I suppose that you want display X objects (in this case two) at a time from an array. Whatever length. I'm using Math lib. Consider that I didn't try the code below with sdk or Flash.
const X_START_POS:int = 125;
const COLUMN_WIDTH:int = 275;
const QTY_SCREEN:int = 2;
var socket_Array:Array = new Array();
var socket_Array_pos:int = 0;
var socket_Array_target:int = 0; // target is always right
var socket_Array_on_screen:Array = new Array();
// socket_Array.length must be >= QTY_SCREEN, always.
socket_Array.push(socket_one, socket_two, socket_three, socket_four, socket_five, socket_six);
go_next_left.addEventListener(MouseEvent.CLICK, go_left);
go_next_right.addEventListener(MouseEvent.CLICK, go_right);
socket_display();
function go_left(going_left:MouseEvent) {
socket_Array_target = Math.max(socket_Array_pos - QTY_SCREEN, 0);
socket_display();
}
function go_right(going_right:MouseEvent) {
socket_Array_target = Math.min(socket_Array_pos + QTY_SCREEN, socket_Array.length - QTY_SCREEN);
socket_display();
}
function socket_display() {
socket_remove();
socket_x_position = X_START_POS;
var limit:int = socket_Array_target + QTY_SCREEN;
for (var i = socket_Array_target; i < limit; i++) {
show_socket(socket_Array[i]);
socket_x_position += COLUMN_WIDTH;
}
socket_Array_pos = socket_Array_target;
}
function show_socket(asocket:DisplayObject) {
addChild(asocket);
asocket.x = socket_x_position;
asocket.y = socket_y_position;
socket_Array_on_screen.push(asocket); // remember me
}
function socket_remove() {
var qty:int = socket_Array_on_screen.length;
for (var s = 0; s < qty; s++) {
removeChild(socket_Array_on_screen.pop());
}
}

Why does my Actionscript 3 program randomly get stuck in an infinite loop?

mBlocks is a 2-dimensional array of Block objects. Every time my application runs, it runs the InitGridNumbers function. Sometimes, it will get stuck in an infinite loop. Other times, it builds and runs without issues.
public function InitGridNumbers():void
{
var tempRow:Array;
var tempColumn:Array;
var tempNum:int;
for (var i:int = 0; i < mNumRows; i++)
{
tempRow = GetRow(i);
for (var j:int = 0; j < mNumColumns; j++)
{
// if number is unassigned
if (tempRow[j] == 0)
{
var cantMoveOn:Boolean = true;
while (cantMoveOn)
{
tempNum = Math.random() * mNumColumns + 1;
if (!CheckRow(i, tempNum) && !CheckColumn(j, tempNum))
cantMoveOn = false;
}
mBlocks[i][j].SetNumber(tempNum);
}
}
}
}
public function CheckRow(rowNum:int, checkNum:int):Boolean
{
var tempRow:Array = GetRow(rowNum);
for (var i:int = 0; i < mNumColumns; i++)
{
if (checkNum == tempRow[i])
return true;
}
return false;
}
public function CheckColumn(columnNum:int, checkNum:int):Boolean
{
var tempColumn:Array = GetColumn(columnNum);
for (var i:int = 0; i < mNumColumns; i++)
{
if (checkNum == tempColumn[i])
return true;
}
return false;
}
public function GetRow(rowNum:int):Array
{
var rowArray:Array = new Array(mNumRows);
for (var i:int = 0; i < mNumRows; i++)
rowArray[i] = mBlocks[rowNum][i].mNumber;
return rowArray;
}
public function GetColumn(columnNum:int):Array
{
var columnArray:Array = new Array(mNumColumns);
for (var i:int = 0; i < mNumColumns; i++)
columnArray[i] = mBlocks[i][columnNum].mNumber;
return columnArray;
}
To begin with, checkColumn, getColumn and getRow methods are wrong. To get a row, you should copy numColumns items and to get a column, you should copy numRows items. In other words, if there are r rows and c columns, there would be c items per each row and r items per each column.
public function checkColumn(columnNum:int, checkNum:int):Boolean
{
var tempColumn:Array = getColumn(columnNum);
for (var i:int = 0; i < mNumRows; i++)
{
if (checkNum == tempColumn[i])
return true;
}
return false;
}
public function getRow(rowNum:int):Array
{
var rowArray:Array = new Array();//needn't specify length in advance.
for (var i:int = 0; i < mNumColumns; i++)
rowArray[i] = mBlocks[rowNum][i].mNumber;
return rowArray;
}
public function getColumn(columnNum:int):Array
{
var columnArray:Array = new Array();
for (var i:int = 0; i < mNumRows; i++)
columnArray[i] = mBlocks[i][columnNum].mNumber;
return columnArray;
}
while (cantMoveOn)
{
//call Math.floor
tempNum = Math.floor(Math.random() * mNumColumns) + 1;
if (!checkRow(i, tempNum) && !checkColumn(j, tempNum))
cantMoveOn = false;
}
It looks like you're checking for a number that is not present in the current row and column. It's hard to say without knowing more details, but can you think of a scenario where this would be impossible?
For example, if there are four columns and five rows, the tempNum would always be between one and four. Now if the number of rows is five and the corresponding column already has all numbers up to four, the if statement would never evaluate to true and hence you'd end up in an infinite loop
0 1 2 3
1
2
3
4
in case grid is a square, how about this:
0 1 2 3
4
0
0