Google apps script store script property value as an integer - javascript

How to store script property value as an integer.
if(PropertiesService.getScriptProperties().getProperty('setnumber'))
{
var setnumber = Number(PropertiesService.getScriptProperties().getProperty('setnumber')) + Number(1);
}
else
{
var setnumber = Number(PropertiesService.getScriptProperties().setProperty('setnumber', 1)); // this value gets stored as 1.0 or returns undefined
}
var numofrow = 500;
var maxvalue = numofrow * setnumber; //returns undefined

The setProperty doesn't returns the value, it rather sets a value to a property. Refer the below code.
var setnumber = 1;
if(PropertiesService.getScriptProperties().getProperty('setnumber'))
{
setnumber = parseInt(PropertiesService.getScriptProperties().getProperty('setnumber')) + 1;
PropertiesService.getScriptProperties().setProperty('setnumber', setnumber);
}
else
{
PropertiesService.getScriptProperties().setProperty('setnumber', setnumber); // you can't assign this to a variable
}
var numofrow = 500;
var maxvalue = numofrow * setnumber; //returns undefined
Logger.log(maxvalue)

Related

Increase integer variable by one on click

I am trying to increase the value for the globally defined variable highestPurposeValue in case the if condition is true, but it does not work. It returns every time 1. What am I doing wrong?
var highestPurposeValue = 0;
$('#addJobPurposeButton').on('click', function(){
var value = $('#jobPurposeInputForm').val();
$('#jobPurposeList li').map(function () {
var item = $(this).find("input[name^='jobPurpose']").attr('name');
var itemNumber = item.match(/\d+/); // returns an array.
if (itemNumber[0] > highestPurposeValue) {
var num = parseInt(itemNumber[0]);
var plusOne = num+1;
highestPurposeValue = plusOne;
}
});

Getting previous objects value in current object

I am using a dataset that contains around 65k data. I am mapping over the dataset multiple times to massage the dataset. After obtaining the dataset in the required format, I am using map to do some computations with the price of the current item. But, whenever I return the current object, it contains the computation data of the previous object.
Whenever I log the data, it always shows the current object and the computations based on the current object. But, the returned object contains a previous object's data. Here is the route:
const {priceBands} = require('../utils/profitComputations');
let profitArray = [];
//calculating the price bands
profitArray = _.map(nfoArray, item=>{
console.log(item.cmp);
//returns the current market price; getting the correct value here
let priceBandVar = priceBands(Number(item.cmp));
console.log(priceBandVar);
//applying some algorithms; getting the correct value here
return {item: item.cmp, profitBand: priceBandVar};
//Here I find a mismatch between the parameter and the calculations
});
Here is the priceBands function in my 'utils/profitComputations':
const _ = require('lodash');
const priceBandInterval = {'-4':0, '-3':0, '-2':0, '-1':0, '0floor':0,'0ceil':0,'1':0, '2':0, '3':0, '4':0};
let priceBands = {};
module.exports = {
priceBands: function(price){
let factor = 0;
if(price>=10000){
factor = 100;
}else if (price>=1000 && price<10000){
factor = 50;
}else if (price>=500 && price<1000){
factor = 25;
}else if (price>=100 && price<500){
factor = 10;
}else if(price>=25 && price<100){
factor = 2;
}else{
factor = 0.5;
}
let priceCeil, priceFloor;
if((price%factor) == 0){
priceCeil = price + factor;
priceFloor = price - factor;
} else {
const remainder = price%factor;
priceCeil = price - remainder + factor;
priceFloor = price - remainder;
}
_.map(Object.keys(priceBandInterval), item=>{
if(parseInt(item)>0){
priceBands[item] = (parseInt(item)*factor) + priceCeil;
} else if (parseInt(item)<0){
priceBands[item] = (parseInt(item)*factor) + priceFloor;
} else {
priceBands['0floor'] = priceFloor;
priceBands['0ceil'] = priceCeil;
}
});
return priceBands;
}
}
I would appreciate if someone can share some valuable insights on what I am missing.
You must clone the variable priceBandVar because javaScript variables are called by reference. The following code is your answer:
profitArray = _.map(nfoArray, item => {
console.log(item.cmp);
//returns the current market price; getting the correct value here
let priceBandVar = priceBands(Number(item.cmp));
console.log(priceBandVar);
//applying some algorithms; getting the correct value here
return {
item: item.cmp,
profitBand: clone(priceBandVar)
};
//Here I find a mismatch between the parameter and the calculations
});
function clone(o) {
var ret = {};
Object.keys(o).forEach(function(val) {
ret[val] = o[val];
});
return ret;
}

Detect change in timer variable using jQuery

I have certain timers which are updating every second. I want to execute some function on change of timer variable. If anyone can help me out. I have provided the code below.
for(var i=0; i<listingTime.length; i++){
if (listingTime[i].time >= 0) {
var second = listingTime[i].time / 1000;
var currentHour = parseInt(second / 3600);
}
}
Here, I want to detect change of currentHour variable.
You can set a previous value variable prior to the loop, and whenever updating the currentHour, just match it with previousValue variable. If they are same, they are not changes, if they are not same, it is changed and you can execute the callback.
One more other way is to use the object prototypes to changes the value of currentHour. Following code shows that:
Above code can be modified to following to add a changeListner
var HourListner = {
currentHour: null,
update: function(newValue, callback){
if(this.currentHour !== newValue){
this.currentHour = newValue;
callback(newValue);
}
}
}
timer = Object.create(HourListner);
var changeListner = function(value){
//value is the new value of currentHour
console.log(value)
}
for(var i=0; i<listingTime.length; i++){
if (listingTime[i].time >= 0) {
var second = listingTime[i].time / 1000;
var currentHour = parseInt(second / 3600);
timer.update(currentHour, changeListner)
}
}
And the trick can be tested independently in following code:
var HourListner = {
currentHour: null,
update: function(newValue, callback) {
if (this.currentHour !== newValue) {
this.currentHour = newValue;
callback(newValue);
}
}
}
timer = Object.create(HourListner);
var changeListner = function(value) {
//value is the new value of currentHour
console.log(value)
$('body').append('<p>'+value+'</p>')
}
var interval = setInterval(function(){
var t = new Date();
timer.update(t.getMinutes(), changeListner)
}, 200)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
This will execute the changeListner if there is a change from previous value.

clone javascript function, closure scope

I have this closure :
function CFetchNextData(ofs, pag, fetchFunction) {
var offset = ofs;
var limit = pag;
return function(options, cb) {
//do stuff to create params
fetchFunction(params, cb);
offset += limit;
};
}
I then create a variable this way:
var fetchInfo = CFetchNextData(0, 10, specificFetchFunction);
fetchInfo(options, myCB);
So that everytime I call fetchInfo, pagination is automatically set to the next set of data. That works great, althought
I'd like to have multiple instance of : "fetchInfo", each one having its own scope.
var A = fetchInfo; // I'd like a clone with its own scope, not a copy
var B = fetchInfo; // I'd like a clone with its own scope, not a copy
I could do:
var A = new CFetchNextData(ofs, pag, fetchFunction);
var B = new CFetchNextData(ofs, pag, fetchFunction);
But obviously I would have to setup "ofs" and "pag" each time, whereas by cloning fetchInfo, I'd have a stable pagination, set only once and for good.
Do you know how to achieve that ?
Thanks in advance
There isn't a concept of cloning a function in JavaScript. You need to call CFetchNextData (or another function) multiple times if you want to create multiple closures.
You could have CFetchNextData return a factory function instead of returning the actual function. But I'm not sure that's really an improvement.
function CFetchNextDataFactory(ofs, pag, fetchFunction) {
return function() {
var offset = ofs;
var limit = pag;
return function(options, cb) {
//do stuff to create params
fetchFunction(params, cb);
offset += limit;
};
};
}
var fetchInfoFactory = CFetchNextData(0, 10, specificFetchFunction);
var A = fetchInfoFactory();
var B = fetchInfoFactory();
This may not answer all of your question but just to pitch in , you could try assigning your parameters to a default / fallback value which will allow you to avoid setting ofs and pag each declaration . Below is a prototype of what I came up with . Its using oop :
class CFetchNextData {
constructor(ofs, pag){
this.OFS = 1; //default value
this.PAG = 10; //default value
this.ofs = ofs;
this.pag = pag;
if(ofs == null || ofs == undefined){
this.ofs = this.OFS;
}
if(pag = null || pag == undefined){
this.pag = this.PAG;
}
}
fetchInfo(){
var data = this.ofs += this.pag;
return data;
}
}
var task1 = new CFetchNextData(); // Falls back to default values..
var task2 = new CFetchNextData(32,31); // Uses values from specified in args...
document.write(task1.fetchInfo() + "\n")
document.write(task2.fetchInfo())
Hope this helps...

Javascript - Error creating objects on the fly

I am trying to simulate data to a function that would usually receive a JSON parsed data structure. When running this I get an error TypeError: can't convert undefined to object here: data.targets[i] = {
What am I doing wrong?
function SendFakeTargets(maxTargets, interval) {
var data = {};
data.timestamp = +new Date;
var time = data.timestamp * 0.0005;
var x = Math.sin(time) * 192 + 256;
var y = Math.cos(time * 0.9) * 192 + 256;
console.log(x, y);
for (var i = 0; i < maxTargets; i++) {
console.log(i);
data.targets[i] = { //error is here
id: i,
x: x + (i * 10),
y: y + (i * 10)
};
}
HandleTargetData(data);
setTimeout("SendFakeTargets("+maxTargets+", "+interval+")", interval);
}
you should previously declare
data.targets = [];
before using data.targets[i] inside the loop, otherwise data.targets is undefined. In a shorter way you could write
var data = {
timestamp : +new Date,
targets : []
};
And as a side note, never use strings in setTimeout/Interval. Do instead
setTimeout(function() {
SendFakeTargets(maxTargets, interval);
}, interval);
I think you need to initialize the targets array before using it, as it is undefined. You are defining data as
var data = {}
which is declaring it as an empty object, anything else that you're doing with it is added on the fly - arrays need to be initialized before you can call any index in them. I believe what you need to do is:
var data = { targets: [] }
You never declared "data.targets" as a an object so javascript doesn't know how to assign anything to it.
At the top of your code just define "targets":
data.timestamp = +new Date;
data.targets = {} or [];
...

Categories