azure asynchronous javascript backend - wait function - javascript

I'm using Azure Mobile Services and a javascript backend. My problem is that the function don't wait the end of an other function.
I'm trying to choose an item (word) with a particolar rules. i want to pick the item with highest item.wordnumber. If there are few item with the same item.wordnumber i want to pick who has a highest avarage of votes associated at that item (in the other table "votes").
This script don't wait the return of function CalcolateMaxAvg.
I would do as I did in c # with await.
var tableWords = tables.getTable('Word');
var tableVotes = tables.getTable('Votes');
var avgVotesActualWord = 0;
var maxItem = null;
var maxItemVote = 0;
function WordChoice() {
var select = tableWords.orderByDescending('wordnumber').read({success:
function (results)
{
results.forEach(function(item)
{
if(maxItem == null)
{
maxItem = item;
maxItemVote = tableVotes.where({idword: item.id}).read({success: CalcolateMaxAvg});
}
else if(item.wordnumber > maxItem.wordnumber)
{
maxItem = item;
maxItemVote = tableVotes.where({idword: item.id}).read({success: CalcolateMaxAvg});
}
else if(item.wordnumber == maxItem.wordnumber)
{
//chack who have more votes
avgVotesActualWord = 0;
avgVotesActualWord = tableVotes.where({idword: item.id}).read({success: CalcolateMaxAvg});
//the problem is avgVoteActualWord that is always NaN
console.log('Word: %s with avg: %d', item.word, avgVotesActualWord);
if(avgVotesActualWord > maxItemVote)
{
//take the actualword because have more votes
maxItem = item;
maxItemVote = avgVotesActualWord;
}
}
})
if(maxItem != null)
{
console.log('parola: %s', maxItem.word);
maxItem.selected = true;
tableWords.update(maxItem);
}
else
{
console.log('null');
}
}
});
}
function CalcolateMaxAvg(resultsVote)
{
var sum = 0;
var count = 0;
var avg = 0;
resultsVote.forEach(function(itemVote)
{
sum = sum + itemVote.vote;
count = count + 1;
})
if(count > 0)
{
avg = sum / count;
}
//this is a correct value of avgVoteActualWord, but he don't wait the return of this value
console.log('avg: %d', avg);
return avg;
}

The problem is that a call to table.where(...).read(...) is asynchronous - it won't return a number returned by the CalcolateMaxAvg function (it won't return anything). You need to rewrite your code to embrace the asynchronicity of JavaScript, something along the lines of the code below.
var tableWords = tables.getTable('Word');
var tableVotes = tables.getTable('Votes');
var avgVotesActualWord = 0;
var maxItem = null;
var maxItemVote = 0;
function WordChoice() {
var select = tableWords.orderByDescending('wordnumber').read({
success: function (results)
{
function processNextResult(index) {
if (index >= results.length) {
// All done
if(maxItem != null)
{
console.log('parola: %s', maxItem.word);
maxItem.selected = true;
tableWords.update(maxItem);
}
else
{
console.log('null');
}
return;
}
var item = results[index];
if (maxItem == null) {
maxItem = item;
tableVotes.where({ idword: item.id }).read({ success: simpleProcessVotesResult });
} else if (item.wordnumber > maxItem.wordnumber) {
maxItem = item;
tableVotes.where({ idword: item.id }).read({ success: simpleProcessVotesResult });
} else if (item.wordnumber == maxItem.wordnumber) {
//check who have more votes
avgVotesActualWord = 0;
tableVotes.where({idword: item.id}).read({
success: function(resultsVote) {
avgVotesActualWord = CalcolateMaxAvg(resultsVote);
//the problem is avgVoteActualWord that is always NaN
console.log('Word: %s with avg: %d', item.word, avgVotesActualWord);
if(avgVotesActualWord > maxItemVote)
{
//take the actualword because have more votes
maxItem = item;
maxItemVote = avgVotesActualWord;
}
processNextResult(index + 1);
}
});
} else {
processNextResult(intex + 1);
}
}
function simpleProcessVotesResult(resultsVote) {
maxItemsVote = CalcolateMaxAvg(resultsVote);
processNextResult(intex + 1);
}
processNextResult(0);
}
});
}
function CalcolateMaxAvg(resultsVote)
{
var sum = 0;
var count = 0;
var avg = 0;
resultsVote.forEach(function(itemVote)
{
sum = sum + itemVote.vote;
count = count + 1;
})
if(count > 0)
{
avg = sum / count;
}
//this is a correct value of avgVoteActualWord, but he don't wait the return of this value
console.log('avg: %d', avg);
return avg;
}

Related

How to Remove Code Duplicates in Below Methods [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
$("#threeToThree").click(function() {
playSound("Start");
executeTimer();
var nextColor = arrangeThreeToThreeColors();
$("#grid .btn").click(function() {
animatePress(this);
if ($(this).attr("id") === nextColor) {
playSound("Success");
totalPoint += 10;
console.log("Total Point: " + totalPoint);
seenColors = [];
nextColor = arrangeThreeToThreeColors();
} else {
playSound("Failure");
}
});
});
$("#fourToFour").click(function() {
playSound("Start");
executeTimer();
var nextColor = arrangeFourToFourColors();
$("#grid .btn").click(function() {
animatePress(this);
if ($(this).attr("id") === nextColor) {
playSound("Success");
totalPoint += 10;
console.log("Total Point: " + totalPoint);
seenColors = [];
nextColor = arrangeFourToFourColors();
} else {
playSound("Failure");
}
});
});
$("#fiveToFive").click(function() {
playSound("Start");
executeTimer();
var nextColor = arrangeFiveToFiveColors();
$("#grid .btn").click(function() {
animatePress(this);
if ($(this).attr("id") === nextColor) {
playSound("Success");
totalPoint += 10;
console.log("Total Point: " + totalPoint);
seenColors = [];
nextColor = arrangeFiveToFiveColors();
} else {
playSound("Failure");
}
});
});
function arrangeThreeToThreeColors() {
for (let i = 0; i <= 12; i++) {
let mod = i % 5;
if (mod === 0 || mod === 1 || mod === 2) {
var randomColor = getValidColor();
manipulateButtons(i, randomColor);
seenColors.push(randomColor);
} else {
continue;
}
}
var nextColor = getRandomColor(seenColors);
$("#next").attr("class", "btn next " + nextColor);
return nextColor;
}
function arrangeFourToFourColors() {
for (let i = 0; i <= 18; i++) {
let mod = i % 5;
if (mod === 0 || mod === 1 || mod === 2 || mod === 3) {
var randomColor = getValidColor();
manipulateButtons(i, randomColor);
seenColors.push(randomColor);
} else {
continue;
}
}
var nextColor = getRandomColor(seenColors);
$("#next").attr("class", "btn next " + nextColor);
return nextColor;
}
function arrangeFiveToFiveColors() {
for (let i = 0; i <= 24; i++) {
var randomColor = getValidColor();
manipulateButtons(i, randomColor);
seenColors.push(randomColor);
}
var nextColor = getRandomColor(seenColors);
$("#next").attr("class", "btn next " + nextColor);
return nextColor;
}
How can I make this code clear code? What is the best way to make this code more readable? Is there a way to implement #threeToThree.click(), #fourToFour.click() and #fiveToFive.click() contents in only one method? And can I combine the contents of arrangeThreeToThreeColors(), arrangeFourToFourColors(), arrangeFiveToFiveColors() in one method?
Added Comments along the code update, take what part of the code refactor best suits you and you can ignore the reset or modify as you want.
1. Using Constants insted of string
const SoundStatus = {
Start: "Start",
Success: "Success",
Failure: "Failure"
};
2. Global variables and using single point of update.
Single point update, would seem too much for simple update. But this will helpful when debugging, as you would know where the variables gets updated.
/**
* I couldn't get the context of these 2 variables; assuming them to be global variables
*/
let seenColors = [];
let totalPoint = 0;
/**
* Using Single setter to update global variables; With this it will be easier to track there changes
*/
function UpdateTotalPoint() {
totalPoint += 10;
}
function ResetSeenColors() {
seenColors = [];
}
function UpdateSeenColors(color) {
seenColors.push(color);
}
3. Removing Duplicate code
/**
* Abstract attribute update to single function
*/
function updateNextAttribute() {
let nextColor = getRandomColor(seenColors);
$("#next").attr("class", "btn next " + nextColor);
return nextColor;
}
function ManipulateButtonAndUpdateSeenColorsWithRandomValue(value) {
const randomColor = getValidColor();
manipulateButtons(value, randomColor);
UpdateSeenColors(randomColor);
}
/**
* Remove contiune on else, as there is no statements to be executed of that; Its understood
*/
function arrangeFiveToFiveColors() {
for (let i = 0; i <= 24; i++) {
ManipulateButtonAndUpdateSeenColorsWithRandomValue(i);
}
return updateNextAttribute();
}
function arrangeFourToFourColors() {
for (let i = 0; i <= 18; i++) {
let mod = i % 5;
if (mod === 0 || mod === 1 || mod === 2 || mod === 3) {
ManipulateButtonAndUpdateSeenColorsWithRandomValue(i);
}
}
return updateNextAttribute();
}
function arrangeThreeToThreeColors() {
for (let i = 0; i <= 12; i++) {
let mod = i % 5;
if (mod === 0 || mod === 1 || mod === 2) {
ManipulateButtonAndUpdateSeenColorsWithRandomValue(i);
}
}
return updateNextAttribute();
}
/**
* Grid Updation
* arrangeColor; will be arrangeThreeToThreeColors, arrangeFourToFourColors or arrangeFiveToFiveColors
*
*/
function AnimateGridButton(nextColor, arrangeColor, context) {
$("#grid .btn").click(function () {
animatePress(context);
if ($(context).attr("id") === nextColor) {
playSound(SoundStatus.Success);
UpdateTotalPoint();
console.log("Total Point: " + totalPoint);
ResetSeenColors();
nextColor = arrangeColor();
} else {
playSound(SoundStatus.Failure);
}
});
}
/**
* Updating click listiner of 3-3, 4-4 & 5-5
*/
$("#threeToThree").click(function () {
initilize();
const nextColor = arrangeThreeToThreeColors();
AnimateGridButton(nextColor, arrangeThreeToThreeColors, this);
});
$("#fourToFour").click(function () {
initilize();
const nextColor = arrangeFourToFourColors();
AnimateGridButton(nextColor, arrangeFourToFourColors, this);
});
$("#fiveToFive").click(function () {
initilize();
const nextColor = arrangeFiveToFiveColors();
AnimateGridButton(nextColor, arrangeFiveToFiveColors, this);
});
/**
* Abstracting inital Start sound and executeTimer
*/
function initilize() {
playSound(SoundStatus.Start);
executeTimer();
}
Final code after Refactoring
const SoundStatus = {
Start: "Start",
Success: "Success",
Failure: "Failure"
};
let seenColors = [];
let totalPoint = 0;
function updateTotalPoint() {
totalPoint += 10;
}
function resetSeenColors() {
seenColors = [];
}
function updateSeenColors(color) {
seenColors.push(color);
}
function updateNextAttribute() {
let nextColor = getRandomColor(seenColors);
$("#next").attr("class", "btn next " + nextColor);
return nextColor;
}
function ManipulateButtonAndUpdateSeenColorsWithRandomValue(value) {
const randomColor = getValidColor();
manipulateButtons(value, randomColor);
updateSeenColors(randomColor);
}
function arrangeFiveToFiveColors() {
for (let i = 0; i <= 24; i++) {
ManipulateButtonAndUpdateSeenColorsWithRandomValue(i);
}
return updateNextAttribute();
}
function arrangeFourToFourColors() {
for (let i = 0; i <= 18; i++) {
let mod = i % 5;
if (mod === 0 || mod === 1 || mod === 2 || mod === 3) {
ManipulateButtonAndUpdateSeenColorsWithRandomValue(i);
}
}
return updateNextAttribute();
}
function arrangeThreeToThreeColors() {
for (let i = 0; i <= 12; i++) {
let mod = i % 5;
if (mod === 0 || mod === 1 || mod === 2) {
ManipulateButtonAndUpdateSeenColorsWithRandomValue(i);
}
}
return updateNextAttribute();
}
function AnimateGridButton(nextColor, arrangeColor, context) {
$("#grid .btn").click(function () {
animatePress(context);
if ($(context).attr("id") === nextColor) {
playSound(SoundStatus.Success);
updateTotalPoint();
console.log("Total Point: " + totalPoint);
resetSeenColors();
nextColor = arrangeColor();
} else {
playSound(SoundStatus.Failure);
}
});
}
$("#threeToThree").click(function () {
initilize();
const nextColor = arrangeThreeToThreeColors();
AnimateGridButton(nextColor, arrangeThreeToThreeColors, this);
});
$("#fourToFour").click(function () {
initilize();
const nextColor = arrangeFourToFourColors();
AnimateGridButton(nextColor, arrangeFourToFourColors, this);
});
$("#fiveToFive").click(function () {
initilize();
const nextColor = arrangeFiveToFiveColors();
AnimateGridButton(nextColor, arrangeFiveToFiveColors, this);
});
function initilize() {
playSound(SoundStatus.Start);
executeTimer();
}
After all the possible abstraction, we are left with code that is specific for each functions; except for ManipulateButtonAndUpdateSeenColorsWithRandomValue (Please come up with a proper name, that would fit the requirment). Couple of lines of abstraction is still possible for arrageColor related functions. Since I don't have a full picture of your requirement, I would leave that to you.

isset equivalent in javascript to find palindrome

I created a script in PHP to find a palindrome, but when I try to do the same in JavaScript, then it is not working as expected. It's not just a matter of checking if the string that is reversed matches, but any order of the string has to be checked as well.
In other words, "mom" should return as true, "mmo" should return as true, "omm" should return as true, etc..., which is what the PHP script does, but the JS script below doesn't even work for the first iteration for the string "mom"
The following is the PHP script:
<?php
function is_palindrom($str) {
$str_array = str_split($str);
$count = array();
foreach ($str_array as $key) {
if(isset($count[$key])) {
$count[$key]++;
} else {
$count[$key] = 1;
}
}
$odd_counter = 0;
foreach ($count as $key => $val) {
if(($val % 2) == 1) {
$odd_counter++;
}
}
return $odd_counter <= 1;
}
echo is_palindrom('mom') ? "true" : "false";
The following is what I have tried in JS:
var count = [];
var strArr = [];
var oddCounter = 0;
var foreach_1 = function(item, index) {
console.log("count[index]: " + count[index]);
if (typeof count[index] !== "undefined") {
count[index]++;
} else {
count[index] = 1;
}
};
var foreach_2 = function(item, index) {
console.log("item: " + item + " item % 2: " + eval(item % 2));
if (eval(item % 2) == 1) {
oddCounter++;
}
console.log("oddCounter: " + oddCounter);
return oddCounter <= 1;
};
var isPalindrom = function(str) {
strArr = str.split("");
console.log(strArr);
strArr.forEach(foreach_1);
console.log(count);
count.forEach(foreach_2);
};
I believe it is failing where I try to replicate isset in javascript, with the following code:
if (typeof count[index] !== "undefined") {
As a result, I have tried to write my own isset function, but still the same result, it is not working:
var isset = function(obj) {
if (typeof obj === "undefined" || obj === null) {
return false;
} else {
return true;
}
};
With the following function being called:
if (isset(count[index])) {
count[index]++;
} else {
count[index] = 1;
}
As usual, any help would be appreciated and thanks in advance
BTW, it's killing me that I cannot remember the word for several revisions or iterations of something - I know that it starts with "re"
My attempt:
let p1 = `No 'x' in Nixon.`
let p2 = `Was it a car or a cat I saw?`
let p3 = `A man, a plan, a canal, Panama!`
function is_palindrome (str) {
const normalize = str => str.replace(/[.,:;`'"!?\/#$%\^&\*{}=\-_~()\s]/g, '').toLowerCase()
const reverse = str => [...str].reverse().join('')
return normalize(str) === reverse(normalize(str))
? true
: false
}
console.log(is_palindrome(p1))
console.log(is_palindrome(p2))
console.log(is_palindrome(p3))
First, thank you for all the comments.
Second, I ran a var_dump on the count array in the PHP file and this was the result:
array (size=2)
'm' => int 2
'o' => int 1
Which lead me to understand that count in js has to be an object for this work and I would have to create indexes of the object, depending on the string entered.
One thing lead to another and a complete re-write, but it works, along with a spell checker - see link at the bottom for complete code:
var count = {};
var strArr = [];
var oddCounter = 0;
var objKeys = [];
var splitString;
var reverseArray;
var joinArray;
var url = "test-spelling.php";
var someRes = "";
var mForN = function(obj, strArr) {
for (var y = 0; y < strArr.length; y++) {
// console.log("obj[strArr[" + y + "]]: " + obj[strArr[y]]);
if (isset(obj[strArr[y]])) {
obj[strArr[y]]++;
} else {
obj[strArr[y]] = 1;
}
}
return obj;
};
var mForN_2 = function(obj, objKeys) {
for (var z = 0; z < objKeys.length; z++) {
/* console.log(
"obj[objKeys[z]]: " +
obj[objKeys[z]] +
" obj[objKeys[z]] % 2: " +
eval(obj[objKeys[z]] % 2)
); */
if (eval(obj[objKeys[z]] % 2) == 1) {
oddCounter++;
}
// console.log("oddCounter: " + oddCounter);
}
return oddCounter <= 1;
};
var isset = function(obj) {
if (typeof obj === "undefined" || obj === null) {
return false;
} else {
return true;
}
};
var isPalindrom = function(str) {
// reverse original string
splitString = str.split("");
reverseArray = splitString.reverse();
joinArray = reverseArray.join("");
var checking = checkSpellingOfStr(str);
if (str == joinArray) {
strArr = str.split("");
// console.log("strArr: " + strArr);
objKeys = makeObjKeys(count, strArr);
// console.log("filled count before mForN: " + JSON.stringify(count));
// create array of keys in the count object
objKeys = Object.keys(count);
// console.log("objKeys: " + objKeys);
count = mForN(count, strArr);
// console.log("count after mForN: " + JSON.stringify(count));
return mForN_2(count, objKeys);
} else {
return 0;
}
};
var makeObjKeys = function(obj, arr) {
for (var x = 0; x < arr.length; x++) {
obj[arr[x]] = null;
}
return obj;
};
var checkSpellingOfStr = function(someStr) {
var formData = {
someWord: someStr
};
$.ajax({
type: "GET",
url: url,
data: formData,
success: function(result) {
if (!$.trim(result)) {
} else {
console.log(result);
$("#checkSpelling").html(result);
}
}
});
};
Start everything with the following call:
isPalindrom("mom") ? demoP.innerHTML = "is pal" : demoP.innerHTML = "is not pal";
In my example, I have a form and I listen for a button click as follows:
var palindromeTxt = document.getElementById("palindromeTxt").value;
var btn = document.getElementById("button");
btn.addEventListener("click", function (event) {
isPalindrom(palindromeTxt) ? demoP.innerHTML = "is pal" : demoP.innerHTML = "is not pal";
});
The following is the php for spell check:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
if(!empty($_REQUEST['someWord']))
{
$someWord = $_REQUEST['someWord'];
}
$pspell_link = pspell_new("en");
if (pspell_check($pspell_link, $someWord)) {
echo trim($someWord) . " is a recognized word in the English language";
} else {
echo "Your word is either misspelled or that is not a recognized word";
}
You will need pspell installed on your server, as well as adding extension=pspell.so to your php.ini
This is what I did, to get it running locally on my mac:
cd /Users/username/Downloads/php-5.6.2/ext/pspell
/usr/local/bin/phpize
./configure --with-php-config=/usr/local/php5-5.6.2-20141102-094039/bin/php-config --with-pspell=/opt/local/
make
cp ./modules/* /usr/local/php5-5.6.2-20141102-094039/lib/php/extensions/no-debug-non-zts-20131226
sudo apachectl restart
check your phpinfo file and you should see the following:
pspell
PSpell Support enabled
Live example

how can i return the count from a function

hi iam new to javascript, i am trying to return a count from the function my code is like below
my code
function moredbCount(contentMoreArray2, ArrHeading) {
var sampleArr = [];
for (var a = 0; a < contentMoreArray2.length; a++) {
if (ArrHeading !== 'More') {
var fullHeading = ArrHeading + '-' + contentMoreArray2[a].name;
} else {
fullHeading = contentMoreArray2[a].name;
}
sampleArr.push(fullHeading);
}
var sampleCount = sampleHeadingCount(sampleArr);
return sampleCount.then(function (resultantCount) {
return resultantCount; //Here iam getting some count like 10 and returning it to the function;
});
}
var contentCount;
var totalCount = moredbCount(contentMoreArray2, ArrHeading);
totalCount.then(function (resultantTotalCount) {
return contentCount = resultantTotalCount
});
// Here i want to use contentCount 10, But iam getting undefined
Thanks In advance
return contentCount = resultantTotalCount won't return the count, but rather the response of assignment. In contentCount = resultantTotalCount, you are basically assigning the value of resultantTotalCount to contentCount.
You should use
function moredbCount(contentMoreArray2, ArrHeading) {
var sampleArr = [];
for (var a = 0; a < contentMoreArray2.length; a++) {
if (ArrHeading !== 'More') {
var fullHeading = ArrHeading + '-' + contentMoreArray2[a].name;
} else {
fullHeading = contentMoreArray2[a].name;
}
sampleArr.push(fullHeading);
}
var sampleCount = sampleHeadingCount(sampleArr);
return sampleCount.then(function (resultantCount) {
return resultantCount; //Here iam getting some count like 10 and returning it to the function;
});
}
var contentCount;
var totalCount = moredbCount(contentMoreArray2, ArrHeading);
totalCount.then(function (resultantTotalCount) {
return resultantTotalCount
});

Is there a javascript library that does spreadsheet calculations without the UI

I am working on a project that needs an excel like calculation engine in the browser. But, it doesn't need the grid UI.
Currently, I am able to do it by hiding the 'div' element of Handsontable. But, it isn't elegant. It is also a bit slow.
Is there a client side spreadsheet calculation library in javascript that does something like this?
x = [ [1, 2, "=A1+B1"],
[2, "=SUM(A1,A2"),3] ];
y = CalculateJS(x);
##############
y: [[1, 2, 3],
[2,3,3]]
I'm not aware of any (although I haven't really looked), but if you wish to implement your own, you could do something along these lines (heavily unoptimized, no error checking):
functions = {
SUM: function(args) {
var result = 0;
for (var i = 0; i < args.length; i++) {
result += parseInt(args[i]);
}
return result;
}
};
function get_cell(position) {
// This function returns the value of a cell at `position`
}
function parse_cell(position) {
cell = get_cell(position);
if (cell.length < 1 || cell[0] !== '=')
return cell;
return parse_token(cell.slice(1));
}
function parse_token(tok) {
tok = tok.trim();
if (tok.indexOf("(") < 0)
return parse_cell(tok);
var name = tok.slice(0, tok.indexOf("("));
if (!(name in functions)) {
return 0; // something better than this?
}
var arguments_tok = tok.slice(tok.indexOf("(") + 1);
var arguments = [];
while (true) {
var arg_end = arguments_tok.indexOf(",");
if (arg_end < 0) {
arg_end = arguments_tok.lastIndexOf(")");
if (arg_end < 0)
break;
}
if (arguments_tok.indexOf("(") >= 0 && (arguments_tok.indexOf("(") < arg_end)) {
var paren_amt = 1;
arg_end = arguments_tok.indexOf("(") + 1;
var end_tok = arguments_tok.slice(arguments_tok.indexOf("(") + 1);
while (true) {
if (paren_amt < 1) {
var last_index = end_tok.indexOf(",");
if (last_index < 0)
last_index = end_tok.indexOf(")");
arg_end += last_index;
end_tok = end_tok.slice(last_index);
break;
}
if (end_tok.indexOf("(") > 0 && (end_tok.indexOf("(") < end_tok.indexOf(")"))) {
paren_amt++;
arg_end += end_tok.indexOf("(") + 1;
end_tok = end_tok.slice(end_tok.indexOf("(") + 1);
} else {
arg_end += end_tok.indexOf(")") + 1;
end_tok = end_tok.slice(end_tok.indexOf(")") + 1);
paren_amt--;
}
}
}
arguments.push(parse_token(arguments_tok.slice(0, arg_end)));
arguments_tok = arguments_tok.slice(arg_end + 1);
}
return functions[name](arguments);
}
Hopefully this will give you a starting point!
To test in your browser, set get_cell to function get_cell(x) {return x;}, and then run parse_cell("=SUM(5,SUM(1,7,SUM(8,111)),7,8)"). It should result in 147 :)
I managed to do this using bacon.js. It accounts for cell interdependencies. As of now, it calculates values for javascript formula instead of excel formula by using an eval function. To make it work for excel formulae, all one has to do is replace eval with Handsontable's ruleJS library. I couldn't find a URI for that library... hence eval.
https://jsfiddle.net/sandeep_muthangi/3src81n3/56/
var mx = [[1, 2, "A1+A2"],
[2, "A2", "A3"]];
var output_reference_bus = {};
var re = /\$?[A-N]{1,2}\$?[1-9]{1,4}/ig
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split('');
function convertToCellRef(rows, cols) {
var alphabet_index = rows+1,
abet = "";
while (alphabet_index>0) {
abet = alphabet[alphabet_index%alphabet.length-1]+abet;
alphabet_index = Math.floor(alphabet_index/alphabet.length);
}
return abet+(cols+1).toString();
}
function getAllReferences(value) {
if (typeof value != "string")
return null;
var references = value.match(re)
if (references.length == 0)
return null;
return references;
}
function replaceReferences(equation, args) {
var index = 0;
return equation.replace(re, function(match, x, string) {
return args[index++];
});
}
//Assign an output bus to each cell
mx.forEach(function(row, row_index) {
row.forEach(function(cell, cell_index) {
output_reference_bus[convertToCellRef(row_index, cell_index)] = Bacon.Bus();
})
})
//assign input buses based on cell references... and calculate the result when there is a value on all input buses
mx.forEach(function(row, row_index) {
row.forEach(function(cell, cell_index) {
if ((all_refs = getAllReferences(cell)) != null) {
var result = Bacon.combineAsArray(output_reference_bus[all_refs[0]]);
for (i=1; i<all_refs.length; i++) {
result = Bacon.combineAsArray(result, output_reference_bus[all_refs[i]]);
}
result = result.map(function(data) {
return eval(replaceReferences(cell, data));
})
result.onValue(function(data) {
console.log(convertToCellRef(row_index, cell_index), data);
output_reference_bus[convertToCellRef(row_index, cell_index)].push(data);
});
}
else {
if (typeof cell != "string")
output_reference_bus[convertToCellRef(row_index, cell_index)].push(cell);
else
output_reference_bus[convertToCellRef(row_index, cell_index)].push(eval(cell));
}
})
})
output_reference_bus["A2"].push(20);
output_reference_bus["A1"].push(1);
output_reference_bus["A1"].push(50);

Run _.each inside while PARSE

I have a table named "circle" and it represents mailing list.
Circle can contain user id in invitedUser or circle id in invitedCircle.
I need to get all circles id that contain specific user (in the code: 1-9).
For example if studantA is in CircleA
CircleA is in CircleB
so i need to get for studantA as output CircleA and CircleB.
I try to find all circles who conect each others by while and each, but the status of the job is : Could not connect to Cloud Code.
How can I run this query until no result found?
Parse.Cloud.job("fillMemberInCircles", function (request, status) {
var studentId = "123456789";
var output = [];
var lowLayer = [];
var highLayer = [];
// Get circles when the student appears in column invitedUsers
var invitedUsers = new Parse.Query("circles");
invitedUsers.equalTo("invitedUsers", studentId);
invitedUsers.find({
success: function (invitedUsersResults) {
if (invitedUsersResults.length > 0) {
for (var i = 0; i < invitedUsersResults.length; i++) {
output.push(invitedUsersResults[i].id);
lowLayer.push(invitedUsersResults[i].id);
}
var counter = lowLayer.length;
var _ = require('underscore.js');
while (counter > 0) {
//var _ = require('underscore.js');
_.each(lowLayer, function (currCircle) {
var invitedCirclesQuery = new Parse.Query("circles");
invitedCirclesQuery.equalTo("invitedCircles", currCircle);
invitedCirclesQuery.find().then(function (results) {
if (results.length != 0) { // item exists
for (var j = 0; j < results.length; j++) {
if (output.indexOf(results[j].id) == -1) {
output.push(results[j].id);
highLayer.push(results[j].id);
}
}
}
}).then(function () {
counter--;
if (counter == 0) {
if (highLayer.length == 0) {
console.log("OK");
lowLayer = [];
status.success("SUCSESS: " + output.length.toString());
} else {
lowLayer = highLayer;
counter = lowLayer.length;
highLayer = [];
}
}
});
});
}
}
//status.success("SUCSESS: " + output.length.toString());
},
error: function () {
status.error("[fillMemberInCircles] There was some error with queryMajors");
}
});
});

Categories

Resources