query object where function filter - mobile

I am trying to implement my business logic in the Azure layer and I just do not grasp this node.js style of scripts on Insert.
I have T-SQL that works for this
declare #latitude decimal(23,20)
declare #longitude decimal(23,20)
declare #timeStamp datetime
set #latitude = 37.7858340000000012537
set #longitude = -122.4064170000000046911
set #timeStamp = '2012-12-25 02:58:23'
select longitude, latitude, userid
from blah.actions ba
where
(
datediff(second, ba.TimeStamp, #timeStamp) < 5 and
(ba.longitude - 0.0001 <= #longitude and ba.longitude + 0.0001 >= #longitude) and
(ba.latitude - 0.0001 <= latitude and ba.latitude + 0.0001 >= latitude)
)
The question is, how do I use a function to filter the table query within an Azure script on Insert?
So a little more work. I figured out how to filter with a function (but I am still struggling with how to debug the Azure scripts). I have the following on my Insert. I have it "working",in the fact that I no longer receive "Internal Server Error", but I have no idea how to log the results or view them (any tips on this Azure stuff are greatly appreciated). I am starting to realize just how much more work I have to do on this application.
function dateDiff(date1, date2)
{
return date1.getTime() - date2.getTime() / 1000;
}
function insert(item, user, request) {
request.execute();
var actionsTable = tables.getTable('BlahActions');
actionsTable.where(function(currentLat, currentLon, currentTime)
{
return (this.Latitude - 0.0001 <= currentLat && this.Latitude + 0.0001 >= currentLat) &&
(this.Longitude - 0.0001 <= currentLon && this.Longitude + 0.0001 >= currentLon) &&
(this.TimeStamp == currentTime);
//(dateDiff(this.TimeStamp, currentTime) <= 5);
}, item.Latitude, item.Longitude, item.TimeStamp)
.read(
{
success:function(results)
{
}
});
}
The problem with the above script is Azure pukes when using the getTime(). I need to grab all of the entries that are close to the same latitude and longitude and that have occurred within the past X seconds (yes, essentially reinventing the "bump"). This is where I am currently stuck. I will update when/if I make it passed this part.

A few lessons learned here.
First and foremost, the Log files are viewable with the menu at the top of the root of the mobile service where it says "LOGS"...#epicFacePalm.
Second, now that I can see the actual error message and not something generic from within my XCode IDE
The return statement inside the predicate for the where method must do simple comparisons only -- you cannot make a call to another method and check the return value in your conditional statements -- that puked on me.
The other technical detail was to change my TimeStamp column from DateTime to double -- completely simplifies the subtraction of the time stamps with no conversions necessary -- simple
With that said, I now have this in the where method
actionsTable.where(function(currentLat, currentLon, currentTime)
{
return (this.Latitude - 0.0001 <= currentLat && this.Latitude + 0.0001 >= currentLat) &&
(this.Longitude - 0.0001 <= currentLon && this.Longitude + 0.0001 >= currentLon) &&
(currentTime - this.TimeStamp <= 5);
}, item.Latitude, item.Longitude, item.TimeStamp)
to filter the results before I filter them in the success callback
.read(
{
success:function(results)
{
for (var i = 0; i < results.length; i++)
{
var obj = results[i];
for(var key in obj)
{
if (key === "id" &&
distance(obj.Longitude, obj.Latitude, item.Longitude, item.Latitude) < 30)
{
}
}
}
}
}
The whole thing for syntax clarity
function insert(item, user, request) {
request.execute();
var actionsTable = tables.getTable('blahActions');
console.log("Inserting new action '%j'", item);
actionsTable.where(function(currentLat, currentLon, currentTime)
{
return (this.Latitude - 0.0001 <= currentLat && this.Latitude + 0.0001 >= currentLat) &&
(this.Longitude - 0.0001 <= currentLon && this.Longitude + 0.0001 >= currentLon) &&
(currentTime - this.TimeStamp <= 5);
}, item.Latitude, item.Longitude, item.TimeStamp)
.read(
{
success:function(results)
{
for (var i = 0; i < results.length; i++)
{
var obj = results[i];
for(var key in obj)
{
if (key === "id" &&
distance(obj.Longitude, obj.Latitude, item.Longitude, item.Latitude) < 30)
{
}
}
}
}
});
}

Related

How to change list values/format?

I'm trying to check a table, that contains "editors" and various "markets" attached to it, and to get a unique list of editors with their number of entries per market.
With this script, I manage to get two list : "editor" and "market":
function JonSnow() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("XX!J1:J114");
var data = range.getDisplayValues();
Logger.log(JSON.stringify(data));
const editor = [];
const market = [];
data.forEach( (val, index) =>{
if(val !="None - regular editor" && val !="N/A" && val !="Cov?" && val !="" && val !="None - no cross-market coverage for this task"){
if(index >= 2 && index <= 12){
markett = "Dach";
}else if (index >= 15 && index <= 30) {
markett = "Dutch";
}else if (index >= 32 && index <= 48) {
markett = "French";
}else if (index >= 52 && index <= 64) {
markett = "Italian";
}else if (index >= 67 && index <= 74) {
markett = "Nordics";
}else if (index >= 77 && index <= 92) {
markett = "polish";
}else if (index >= 95 && index <= 114) {
markett = "Uk";
};
editor.push(val)
market.push(markett)
} else {
return
};
});
Logger.log(editor);
Logger.log(market);
const edunique = [...new Set(editor)];
My next steps would have been to get a list of unique editors and with loops, counting the number of market entries. Problem is, the [...new Set(editor)], doesn't work, and I believe it's because my "editor" list returns [[Name1],[Name2],[Name1]], and should return ["Name1","Name2","Name1"] to work.
Here are my questions :
How do you call to a format like that ? [[],[],[]]
Where did I went wrong and got this ?
How can I fix this, or prevent it ?
Thanks a lot!!
(Sorry if my title is not helpful, as I have no idea what to call the issue I have)
The Range..getDisplayValues() function gets a 2D array. To get a 1D array, use Array.flat(), like this:
const data = range.getDisplayValues().flat();

Pagination is not working in angular JS when the items is below 12 and more than 10

I am using this <github.com/michaelbromley/angularUtils-pagination> Url code. I can able to see the data coming to UI but the pagination is not working consistantly. when there are more than 12 items the pagination is working when there are are less than 12 and more than 10 pagination is not working properly. Please refer to the URL above and suggest a solution. we are suspecting the below code. But not sure where the issue is:
function generatePagesArray(currentPage, collectionLength, rowsPerPage, paginationRange) {
var pages = [];
var totalPages = Math.ceil(collectionLength / rowsPerPage);
var halfWay = Math.ceil(paginationRange / 2);
var position;
if (currentPage <= halfWay) {
position = 'start';
} else if (totalPages - halfWay < currentPage) {
position = 'end';
} else {
position = 'middle';
}
var ellipsesNeeded = paginationRange < totalPages;
var i = 1;
while (i <= totalPages && i <= paginationRange) {
var pageNumber = calculatePageNumber(i, currentPage, paginationRange, totalPages);
var openingEllipsesNeeded = (i === 2 && (position === 'middle' || position === 'end'));
var closingEllipsesNeeded = (i === paginationRange - 1 && (position === 'middle' || position === 'start'));
if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
pages.push('...');
} else {
pages.push(pageNumber);
}
i++;
}
return pages;
}

Issues reading cells using map() in a range in Google Sheets

I have a function that works perfectly when assigning it on a per-cell basis, but when I try to create an array using the map() function, cell values are not being read properly. Can anyone help on this?
I've tried to read up on this and it might have something to do with Google Sheets map() function not being able to handle certain scenarios because all calcs are being done server-side? Not sure.
Anyway, I'm trying to read dates from one column, and see whether there was a discount in another column, and based on the date and discount token "DSC", return a percent discount value: 25% for or 30% if between 2 dates.
Picture of no 30% values in 3rd column
Below is the code for the working function (assigned to each cell) and non-working map() function assigned to a range then a Google Sheets link:
// ==================================== Using .map
/**
#customfunction
*/
function Disc_Perc_Map (input1, input2){ // input1 is product ID column, input2 is Date
var Date_1_a = Date.parse(String("1/3/2017")) ;// put start date of discount change here
var Date_1_b = Date.parse(String("1/4/2017")) ;// put end date of discount change here
var Disc_Def = .25;
var Disc_1 = .30;
if (input1.map){ // Checks if array
return input1.map(Disc_Perc_Map); // added along with added brace at end
} else {
// Main part of code
if (String(input1).indexOf(",") >-1) { // if there are commas
Cell_Array = input1.split(",");
Cell_Len = input1.split(',').length;
var Date_Num = Date.parse(String(input2));
if (Date_Num >= Date_1_a && Date_Num <= Date_1_b){
return Disc_1;
} else {
return Disc_Def;
}
} else { // if there are NO commas
return "";
//Cell_Len = 1;
}
}
}
// ==================================== without using .map
/**
#customfunction
*/
function Disc_Perc_No_Map(input1, input2) { // input1 is product ID column, input2 is Date
var Date_1_a = Date.parse(String("1/3/2017")) ;// put start date of discount change here
var Date_1_b = Date.parse(String("1/4/2017")) ;// put end date of discount change here
var Disc_Def = .25;
var Disc_1 = .30;
// Main part of code
if (String(input1).indexOf(",") > -1) { // if there are commas
Cell_Array = input1.split(",");
Cell_Len = input1.split(',').length;
var Date_Num = Date.parse(String(input2));
if (Date_Num >= Date_1_a && Date_Num <= Date_1_b){
return Disc_1;
} else {
return Disc_Def;
}
} else { // if there are NO commas
return "";
//Cell_Len = 1;
}
}
Link to example Google Sheets:
Any help great appreciated.
I think that the reason of issue is as follows.
When Disc_Perc_Map() do the callback, input2 becomes the index of input1.map().
So the values of input2 inputted from the custom function is removed from the running script.
In order to avoid this issue, how about this modification?
Modification points :
Backup input2 and use in the callback.
In order to use the backed up input2, add a counter.
Retrieve the date value using the counter.
Modified script :
var cnt = -1; // Added
var input2bk; // Added
function Disc_Perc_Map (input1, input2){ // input1 is product ID column, input2 is Date
if (isNaN(input2)) input2bk = input2; // Added
var Date_1_a = Date.parse(String("1/3/2017")) ;// put start date of discount change here
var Date_1_b = Date.parse(String("1/4/2017")) ;// put end date of discount change here
var Disc_Def = .25;
var Disc_1 = .30;
if (input1.map){ // Checks if array
return input1.map(Disc_Perc_Map); // added along with added brace at end
} else {
cnt += 1; // Added
// Main part of code
if (String(input1).indexOf(",") > -1) { // if there are commas
Cell_Array = input1.split(",");
Cell_Len = input1.split(',').length;
var Date_Num = Date.parse(String(input2bk[cnt][0])); // Modified
if (Date_Num >= Date_1_a && Date_Num <= Date_1_b){
return Disc_1;
} else {
return Disc_Def;
}
} else { // if there are NO commas
return "";
//Cell_Len = 1;
}
}
}
Another pattern :
As an another pattern, how about this modification? This is also the same result with above.
function Disc_Perc_Map (input1, input2) { // input1 is product ID column, input2 is Date
var Date_1_a = Date.parse(String("1/3/2017")) ;// put start date of discount change here
var Date_1_b = Date.parse(String("1/4/2017")) ;// put end date of discount change here
var Disc_Def = .25;
var Disc_1 = .30;
return input1.map(function(e, i) {
// Main part of code
if (String(e[0]).indexOf(",") > -1) { // if there are commas
Cell_Array = e[0].split(",");
Cell_Len = e[0].split(',').length;
var Date_Num = Date.parse(String(input2[i][0])); // Modified
if (Date_Num >= Date_1_a && Date_Num <= Date_1_b) {
return [Disc_1];
} else {
return [Disc_Def];
}
} else { // if there are NO commas
return [""];
//Cell_Len = 1;
}
});
}
If I misunderstand your question, I'm sorry.

Function inside JSX, is not returning the elements: ReactJS

I am trying to add extra rows on a table that is generated using results.map, but the code that I have added to generate the extra rows isn't executing. Does anyone know why this wouldn't work?
< tbody >
{
results.map(result => {
let rowNodes = [];
rowNodes.push(<td className="hidden">{result.itemCtrlType}</td>);
if (this.props.gridNumber == 1) {
rowNodes.push(<td className="in-td-item">{result.metric}</td>);
} else {
rowNodes.push(<td className="in-td-item hidden">{result.metric}</td>);
}
for (const hour in result) {
if (hour.indexOf('t') == 0 && hour.length == 3) {
let now = Date.now();
let d = new Date(now);
let hours = d.getHours();
let time = hours.toString();
if (hours < 10) {
time = 't0' + hours;
}
else {
time = 't' + hours;
};
let classname = "in-td";
if (hour == time && this.props.dateAdjust == 0) {
classname += " cell-timenow";
}
if (hour == 't23') {
classname += " table-lastcolumn";
}
let date = [pad(d.getMonth() + 1), pad(d.getDate()), d.getFullYear()].join('/');
rowNodes.push(<td key={hour} className={classname} >{result[hour]}</td>)
}
}
if (this.props.gridNumber == this.props.totalGrids) {
rowNodes.push(<td className="in-td-addcolumn in-td"></td>);
}
return <tr key={result.metric} onClick={this.handleClick}>{rowNodes}</tr>
})
}
{
() => {
console.log(this.props.rowsCount > results.length);
if (this.props.rowsCount > results.length) {
let diff = this.props.rowsCount - results.length;
var rowNodes = [];
for (let m = 0; m < diff; m++) {
rowNodes.push(<td className="hidden"></td>);
if (this.props.gridNumber == 1) {
rowNodes.push(<td className="in-td-item"></td>);
} else {
rowNodes.push(<td className="in-td-item hidden"></td>);
}
for (let n = 0; n < 24; n++) {
rowNodes.push(<td className="in-td"></td>);
}
if (this.props.gridNumber == this.props.totalGrids) {
rowNodes.push(<td className="in-td-addcolumn in-td"></td>);
}
return <tr>{rowNodes}</tr>
}
}
}
}
</tbody>
I have tried various combinations of wrapping it in divs or changing where it returns but nothing seems to work.
Anyone know why this isn't firing?
First of all, that is not a good way of organising code, instead of putting the function directly inside JSX, better to define it outside of render method and then call.
Solution:
Issue with your code is, you defined a function inside JSX, but you are not calling it, Use IIFE and call that function, also return null when if condition fails, Like this:
{
(() => {
console.log(this.props.rowsCount > results.length);
if (this.props.rowsCount > results.length) {
let diff = this.props.rowsCount - results.length;
var rowNodes = [], elements = [];
for (let m = 0; m < diff; m++) {
rowNodes = [];
rowNodes.push(<td className="hidden"></td>);
if (this.props.gridNumber == 1) {
rowNodes.push(<td className="in-td-item"></td>);
} else {
rowNodes.push(<td className="in-td-item hidden"></td>);
}
for (let n = 0; n < 24; n++) {
rowNodes.push(<td className="in-td"></td>);
}
if (this.props.gridNumber == this.props.totalGrids) {
rowNodes.push(<td className="in-td-addcolumn in-td"></td>);
}
elements.push(<tr key={m}>{rowNodes}</tr>);
}
return elements;
}
return null;
})()
}
Note:
Whenever execution find return statement inside for loop, it will immediately break the loop and return that result, so instead of using return use one more variable and put the tr inside that, Return the result only after for loop completion.
Suggestion:
Assign unique key to each dynamically created elements inside loop.
Check DOC.
Check this answer for more details about keys: Understanding unique keys for array children in React.js

JavaScript timer is resetting while refreshing the page

I got a count down timer script.. I'm going to use it for a online examination.. But now the problem is it is resetting while refreshing the page...
Any idea to prevent the resetting the time and continue without any problem if they refresh the page too?
here is the code
<script>
var mins;
var secs;
function cd() {
mins = 1 * m("2"); // change minutes here
secs = 0 + s(":01"); // change seconds here (always add an additional second to your total)
redo();
}
function m(obj) {
for(var i = 0; i < obj.length; i++) {
if(obj.substring(i, i + 1) == ":")
break;
}
return(obj.substring(0, i));
}
function s(obj) {
for(var i = 0; i < obj.length; i++) {
if(obj.substring(i, i + 1) == ":")
break;
}
return(obj.substring(i + 1, obj.length));
}
function dis(mins,secs) {
var disp;
if(mins <= 9) {
disp = " 0";
} else {
disp = " ";
}
disp += mins + ":";
if(secs <= 9) {
disp += "0" + secs;
} else {
disp += secs;
}
return(disp);
}
function redo() {
secs--;
if(secs == -1) {
secs = 59;
mins--;
}
document.getElementById("disp").innerHTML=dis(mins,secs); // setup additional displays here.
if((mins == 0) && (secs == 0)) {
window.alert("Time is up. Press OK to continue."); // change timeout message as required
// window.location = "yourpage.htm" // redirects to specified page once timer ends and ok button is pressed
} else {
cd = setTimeout("redo()",1000);
}
}
function init() {
cd();
}
window.onload = init;
</script>
If the page is refreshed, all you javascript code is re-executed. This is normal behaviour.
If you absolutely need to continue where you left, you can use the local storage API (only available in modern browsers) to store the time (every second you update the value).
When the page is loaded, you can then check if the value exists in Local storage, and start from where you were.
Are you sure you need this behaviour BTW?

Resources