I am working on an Footballing angular JS webb app using Firebase as the backend. Below is the JS of one view:
databaseService.users.child(user.uid).once('value', function(usersSnapshot){
var users = usersSnapshot.val();
var selection = users.selection;
var team = users.teamname;
var week1 = users.week1;
var week2 = users.week2;
var week3 = users.week3;
var week4 = users.week4;
var week5 = users.week5;
var week6 = users.week6;
var week7 = users.week7;
var week8 = users.week8;
var week9 = users.week9;
var week10 = users.week10;
var week11 = users.week11;
var week12 = users.week12;
$scope.$watch('players', function (newValue, oldValue) {
$scope.totalPoints =(newValue, 'goals');
firebase.database().ref("users").child(user.uid).child("week12");.set($scope.totalPoints);
},true);
So basically the player weekly goals are watched and reflected in the view, after which the updated goal tally of a player is $set to a firebase node.
Below are the lines of code used to then update the the season goal tally:
var addition = week1 + week2 + week3 + week4 + week5 + week6 + week7 + week8 + week9 + week10 + week11 + week12;
var seasonTotal = firebase.database().ref("users").child(user.uid).child("total");
seasonTotal.set(addition);
on the Second view, I have the following code to show the value of firebase.database().ref("users").child(user.uid).child("total"); :
databaseService.users.child(user.uid).on('value', function(usersSnapshot){
var users = usersSnapshot.val();
var total = users.total;
$scope.total = total;
My Issue
My issue is that when i change the goal tally of a player in my firebase databse weekly node directly (As would be done each week), the goal update is reflected in the first view in real time. However, when I am on the second view, and I make the change in my database, the change update does not reflect in real time (the total goal tally for the weeks); the page needs to be refreshed or i need to return to the first view AND THEN go back to the second view.
I understand that this is because the code that adds up the weekly goals is in the first JS and not the JS for the second view. But is there a way to get the season total to update irrespective of the page the user is on?
Related
I am trying create a script for Google Sheets that does the following:
1) triggers on a certain date
2) compiles information from columns based on a date criteria
3) sends an email digest of multiple column values to each unique triggered email row
I've looked up several alternate examples, but I cannot grasp the syntax to handle step 3.
The data is generated from Google Forms submissions.
Submissions are added continuously. Script has a time-driven trigger.
I want it to compile all data for entries by the SAME email respondent on the triggered date AND separate out data intended for different email addresses.
I've grabbed a script and altered it to the best of my ability. (see below)
Currently, it produces the following results:
1) script triggers correctly based on date
2) compiles information from triggered columns and reports in one email to all addresses from triggered rows. (incorrect behavior)
Currently the script runs a 'for loop' to grab all triggered data for body of email and sends ALL data to ALL emails. I understand why it does this but I can't wrap my head around how to execute 'step 3' above.'
I think I need to create an object for the email data and run another "for loop" to isolate the reference email.
I'm not sure where to go from here, or how to grab the column value to isolate the required email.
Spreadsheet layout:
Column A: Timestamp
Column B: Recorded Email
Column C - F: Personalized Info
Column G: Requested Followup Date
Column H: Days Remaining until Followup Date
Data set starts on Row 2
Email is triggered when Column H reports value of 0.
Thank you in advance for any and all assistance
Current Script:
function checkReminder() {
// get the spreadsheet object
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// set the first sheet as active
SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);
// fetch this sheet
var sheet = spreadsheet.getActiveSheet();
// figure out what the last row is
var lastRow = sheet.getLastRow();
// the rows are indexed starting at 1, and the first row
// is the headers, so start with row 2
var startRow = 2
// grab column 8 (the 'days left' column)
var range = sheet.getRange(2,8,lastRow-startRow+1,1);
var numRows = range.getNumRows();
var reminder_date = range.getDisplayValues();
//grab DOB column
var DOB = sheet.getRange(2,4,lastRow-startRow+1,1)
var DOBrange = DOB.getDisplayValues();
//grab ph# column
var phnum = sheet.getRange(2,5,lastRow-startRow+1,1)
var phnumrange = phnum.getDisplayValues();
//Admin Date of 1st shot
var Admindate = sheet.getRange(2,6,lastRow-startRow+1,1)
var Admin = Admindate.getDisplayValues();
// Now, grab the patient name column
range = sheet.getRange(2,3, lastRow-startRow+1,1);
var patient_info_values = range.getValues();
//grab email
var Emailrows = sheet.getRange(2,2,lastRow-startRow+1,1);
var Emaillist = Emailrows.getValues();
var sendit = 0;
var msg = "";
var greeting = "This email is to remind your team to followup with the following individuals. \n \n";
// Loop over the days left values
for (var i = 0; i <= numRows - 1; i++) {
var days_left = reminder_date[i][0];
if(days_left == 0) {
// if it's equal to 0, do something with the data.
var Adminreport = Admin[i][0];
var patient_name = patient_info_values[i][0];
var DOB_name = DOBrange[i][0];
var phnumgrab = phnumrange[i][0];
msg = msg + " "+patient_name+" DOB: "+DOB_name+" Phone#: "+phnumgrab+" First dose given "+Adminreport+" \n\n";
sendit++;
}
}
if(sendit)
{
MailApp.sendEmail(Emaillist, "Followup Reminder", greeting + msg);
}
};
I'm trying to solve this question but despite the effort I have not advanced!
Every day I get a spreadsheet with two tabs of data. Each one has about 9 thousand rows. I need to capture the data from this worksheet and generate two new spreadsheets with one for "daily reporting" (with only the data of this day) and another for create a "database" (with all data previous results). How can I do this automatically with GAS?
I working in this code below so far, but when I will set the values in the new spreadsheet, I got error about range. :( I don't know how to declare that I want copy and set all the rows between 10 and the last with data from
function getData() {
var day = SpreadsheetApp.openById('XXXX');
var tab1 = day.getSheets()[0];
var tab2 = day.getSheets()[1];
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sss = ss.getSheets()[0];
var weeks = tab1.getRange("G8").getValues();
var dates = tab1.getRange("G9").getValues();
var regions = tab1.getRange('A10:A').getValues();
var locnames = tab1.getRange('B10:B').getValues();
var locnums = tab1.getRange('C10:C').getValues();
var divisions = tab1.getRange('D10:D').getValues();
var depnums = tab1.getRange('E10:E').getValues();
var depnames = tab1.getRange('F10:F').getValues();
var saless = tab1.getRange('G10:G').getValues();
var qtys = tab2.getRange('G10:G').getValues();
var datestart = sss.getRange('A2').setValues(dates);
var dateend = sss.getRange('B2').setValues(dates);
var week = sss.getRange('C2').setValues(weeks);
var region = sss.getRange('D2:D').setValues(regions);
var locname = sss.getRange('E2:E').setValues(locnames);
var locnum = sss.getRange('F2:F').setValues(locnums);
var division = sss.getRange('G2:G').setValues(divisions);
var depnum = sss.getRange('H10:H').setValues(depnums);
var depname = sss.getRange('I2:I').setValues(depnames);
var sales = sss.getRange('J2:J').setValues(saless);
var qty = sss.getRange('K2:K').setValues(qtys);
}
If anyone can help me, thank you immensely.
I put a spreadsheet in the link to illustrate the format of sheets and what I need to do. The first two tabs are the same as the ones I get. And in the next two tabs(daily_report, database) are the worksheets that I want to get separately with the code.
https://docs.google.com/spreadsheets/d/1_iz0oansAfINosV2qNoDG0QMNpGS1bp1AL5kJQztRtc/edit?usp=sharing
The target range must be matched to the source range, or there will be an error. The length and width of the target range must be the same as the source data. You can use the data to set the length (number of rows) and width (number of columns)
Parameters:
range(Start Row, Start Column, Number of Rows, Number of Columns)
Code:
var regions = tab1.getRange('A10:A').getValues();
var region = sss.getRange(2,4,regions.length,regions[0].length).setValues(regions);
Ok so I'm using routing to drill down into a specific item based on it's ID (but also capturing it's category)
$http.get('http://something.co.uk/?category='+$routeParams.storyCat+'&id='+$routeParams.storyID)
This gives a URL of http://website.co.uk/index.html#/category/103 with the story details coming from the data on the server based on the ID of the item you clicked.
The following functions are then run on swipe (using angular-touch) which increase or decrease the ID by one, showing the next or previous story.
$scope.nextStory = function () {
var storyID = Number($routeParams.storyID);
var storyCat = $routeParams.storyCat;
var path = '/' + storyCat + '/' + (storyID + 1 );
$location.path(path);
};
$scope.previousStory = function () {
var storyID = Number($routeParams.storyID);
var storyCat = $routeParams.storyCat;
var path = '/' + storyCat + '/' + (storyID - 1 );
$location.path(path);
};
The problem with this is that it literally just goes up and down the ID's. I need it to only go through ID's which match the Category of the item you are on.
For example if you click into story ID 95, which is in a category called "Bags" and then you swipe left, I need it to not simply show story 96 which might be in a different category, but instead find the next story within "Bags" and show that one.
Can this even be done using AngularJS and routing or do I need a completely different approach?
I have a requirement where I want to display say the first 10 entries in a list and once the user scrolls down I would like to append the next 10 entries. I am currently using Angularfire and all the documentation specifies that I should not do array operations on a $FirebaseArray:
This array should not be directly manipulated. Methods like splice(), push(), pop(), and unshift() will cause the data to become out of sync with server.
So my options are to load the next 10 entries and:
Use $add(), which would write them to the server again (think this could cause some nasty recursion)
Use concat, in which case my data will get out of sync with the server
Get the list again but adjust the limit to be 20, which I think would cause all the data to be reloaded defeating the purpose of lazy loading.
Here is the code that initially loads the list (based on the Angularfire seed app):
var lastKey = null;
var firstKey = null;
$scope.messages = fbutil.syncArray(userMessages,{'limit':10});
$scope.messages.$loaded(function(data){
lastKey = data.$keyAt(data.length-1);
firstKey = data.$keyAt(0);
});
And here is the code that is triggered when the user scrolls down:
$document.on('scroll', function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
var newMessages = fbutil.syncArray(messagePath,{'limit':10,'startAt':lastKey});
newMessages.$loaded(function(data){
lastKey = data.$keyAt(data.length-1);
firstKey = data.$keyAt(0);
$scope.messages.concat(newMessages);// this is probably a bad idea
});
}
});
Based on Kato's comment the following is the best solution given the current API.
var limit= 10;
$scope.messages = fbutil.syncArray(messagePath,{'limit':limit});
And the scroll trigger
$document.on('scroll', function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
limit += 10;
$scope.messages = fbutil.syncArray(messagePath,{'limit':limit});
}
});
I have performance issue on salesforce
I am trying to load table from salesforce into excel cvs, for that used, I tested the ApexDataLoader and found out that to load whole lead table for my organization take around 4~5 min, and have around 60,000 records.
Now I want to do the same with a C# code, for that I write this code:
var user = "xxx";
var password = "xxx";
var token = "xxx";
var sforceService = new SforceService();
var login = sforceService.login(user, String.Concat(password, token));
sforceService.Url = login.serverUrl;
sforceService.SessionHeaderValue = new SessionHeader { sessionId = login.sessionId };
var query = "The full query that I took from ApexDataLoder";
var startTime = DateTime.Now.TimeOfDay;
var firstTime = DateTime.Now.TimeOfDay;
var result = sforceService.query(query);
int i = 0;
while (!result.done)
{
var endTime = DateTime.Now.TimeOfDay;
Debug.Print(endTime.Subtract(startTime) + " " + i * result.records.Count() + " - " + (i + 1) * result.records.Count() +
" Time from start: " + endTime.Subtract(firstTime));
startTime = DateTime.Now.TimeOfDay;
result = sforceService.queryMore(result.queryLocator);
i++;
}
After few lines I saw that I read only 2000 lines in total (out of 60,000) in 2 miniuts.
That's mean that to get the whole table I will need 60 min.
Why there is so big difference between that ApexDataLoader (5 min) to my code? what I am doing wrong?
Thanks for the help!
I found 2 things that really improve performance,
one, set up the EnableDecompression to true
sforceService.EnableDecompression = true;
And the second is based on this thread, it is better to do a query "select Id from Lead" and collect all the id's and then do a multi thread processing to get the data with the retrieve function.
Hope that will help people and if someone have any other improvement tricks, please let me know