Storing functions within arrays - javascript

I'm having a issue with something very simple. I am just wondering as to I can store these functions within an array. Check out some of the code below. I am unsure as to if this is correct as to how I am storing these functions. I am unsure as to if these functions should be within a object literal or array.This is not necessarily for a project, just good practice. Thanks!
//declaring a function
function alert_name(){
//declaring variables within a function asking user their name.
var username = prompt("Hey there, what is your name."," ");
//generating user input
var chameleon = "Welcome " + username;
//combinators
//alert("Welcome " + chameleon+ ", This is 'the website");
};
// inserting quotes into a string that is being alerted from the browser.
function otherTHings(){
var single = 'He said \'RUN\' ever so softly.';
//alert(single);
};
//running these functions and actually carry out the operations
//that have actually been declared into code above.
//string operations
function string_opertaions(){
var complete = "Com" + "plete";
//alert(complete);
// using combinators to do the same thing.
var sentance1 = "My name is";
var sentance2 = "someone";
var totalsenatces = sentance1 += sentance2;
//alert(totalsenatces);
};
//Booleans or true false values
function booleanys(){
var lying = false;
var truthful = true;
};
//Arrays very important. very similar to a object literal but different.
//Arrays store information or values or varibales/data.
var rack = [];
rack[0] = alert_name();
rack[1] = otherTHings();
rack[2] = string_opertaions();
rack[3] = booleanys();
//alert_name();
//otherTHings();
//string_opertaions();
//booleanys();

You are invoking the function and storing the result!
var rack = [];
rack[0] = alert_name;
rack[1] = otherTHings;
rack[2] = string_opertaions;
rack[3] = booleanys;

Related

String 'Regex' Validation for below scenario

var variables = ['A','B'];
var allowedMathFunc = ['Sin','Cos','Tan']
var expression= 'Sin(B)+Tan(B)+100+acos(A)+C'
I want to validate expression string match below scenario
expression should use variables array values
expression should not contain other then allowed math functions.
I tried below code
var variables = ['A','B'];
var allowedMathFunc = ['Sin','Cos','Tan']
var expression= 'Sin(B)+Tan(B)+100+acos(A)'
for variable check I tried this
let expressionVariables = value.replace(/Sin|Log|Exp|Tan|Pos|Rnd|[^A-Za-z]/ig,"");
let expressionUnUsedVar= variables.filter(v=> !expressionVariables.includes(v));
I don't know how to write for both scenario for regex it's not a problem for two different regex.
You can use regex to extract all variables and function names, and then check them if they're included in the allowed function and variable lists (case sensitive):
function testExpression(expression, vars, funcs) {
const usedVariables = expression.match(/\b[a-z]+\b(?!\s*\()/gi);
const usedFunctions = expression.match(/\b[a-z]+\b(?=\s*\()/gi);
return usedVariables?.every(v => vars.includes(v)) && usedFunctions?.every(func => funcs.includes(func));
}
var variables = ['A','B'];
var allowedMathFunc = ['Sin','Cos','Tan']
var expression= 'Sin(B)+Tan(B)+100+acos(A)+C'
console.log(testExpression(expression, variables, allowedMathFunc));
console.log(testExpression('Sin(B)+Tan(B)+100+Cos(A)+C', ['A','B','C'], ['Sin','Cos','Tan']));

Using Array.splice removes strings from two arrays

So this is what I am dealing with:
At the top of the js file i declare these variables:
let teensArray = [];
let copyteensArray = [];
let teensArrayLength = 0;
let teensArrayPlayed = 0;
$.getJSON("json/teens.json", function(data) {
teensArray = data.statements;
copyteensArray = data.statements;
teensArrayLength = data.statements.length;
$(".teens .total-cards").text(teensArrayLength + " CARDS")
});
Everytime the mode is "teens" this executes:
if (mode == "teens") {
let currStatement = copyteensArray[getRandomInt(copyteensArray.length)]
let index = copyteensArray.indexOf(currStatement)
copyteensArray.splice(index, 1);
currentPack = "TEENS PACK";
currentColor = "#23B574";
srcImg = "svg/007-party hat.svg"
playedCardsText = ++teensArrayPlayed + " / " + teensArrayLength;
console.log(copyteensArray.length);
console.log(teensArray.length);
return currStatement;
}
The problem: The teensArray has the same values as copyteensArray after the if statement.
Example values:
Before if statement
teensArray["1","2","3","4"]
copyteensArray["1","2","3","4"]
Inside if statement
copyteensArray.splice(index, 1);
After the return inside the if statement
teensArray["1","3","4"]
copyteensArray["1","3","4"]
This function executes ONLY if the user decides to go back to another screen:
function reset() {
copyteensArray = teensArray;
teensArrayPlayed = 0;
}
Am I missing something?
copyteensArray = teensArray; makes the same pointer point to both of them. Consider using copyteensArray = [...teensArray]; which assigns brand new instance of teensArray content to copyteensArray
You have a "shallow" copy of the array, ie both the array point to the same objects. Any changes made to the shallow copy will change the original object.
You can visualize it as a shortcut in Windows. Whatever change you make to the shortcut also changes the original object.
Solve this making a hard copy. There are multiple ways in ES6 to do that.
hardCopy = [...OriginalArray];
And another way is to JSON.stringify() the object and parse it back.
hardCopy = JSON.parse(JSON.stringify(OriginalArray));
For your code, fix this by changing these lines
$.getJSON("json/teens.json", function(data) {
teensArray = [...data.statements];
copyteensArray = [...data.statements];

Javascript array when referenced errors with object not found

I am trying to retrieve the data from a ADO recordset and load it into an array using javascript.
The data seems to be loading in fine ( as the alert shows the correct length) but when i try to reference one of the object values it give the following "Object is no longer valid"
The code is as follows
var adoConn = new ActiveXObject("ADODB.Connection");
var adoRS = new ActiveXObject("ADODB.Recordset");
var db_name = "C:\\HMRC\\xxx.accdb";
var csv = "user_id, date_corrected, tot_corrected \n";
var rec_obj = {};
function get_record()
{
var i = 0 ;
var master_arr = [];
adoConn.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + db_name);
adoRS.Open("Select * From tot_corr_ent", adoConn, 1, 3);
while (!adoRS.eof)
{
rec_obj["user_id"] = adoRS.Fields("user_id");
rec_obj["date_corrected"] = adoRS.Fields("date_corrected");
rec_obj["tot_ent"] = adoRS.Fields("tot_ent");
master_arr.push(rec_obj);
adoRS.MoveNext;
i++;
}
alert ( "Out of the loop ");
adoRS.close();
adoConn.close();
alert ( "connection closed ");
alert("Final alert: " + master_arr.length);
alert("Final alert 2: " + master_arr[0].user_id); -- **errors at this line**
}
Thanks in advance!
The error you are seeing is likely to be because you are storing a reference to the ADODB Field and not the value. This reference goes out of scope when you closed the connection. You need to copy the value you want from the Field object into your object. I don't know ADODB but it looks like you need to access the Value property of the Field
As #Rajesh said in his comment you are adding n copies of the same reference into master_arr. Change the while loop to:
while (!adoRS.eof) {
var rec_obj = {}
rec_obj["user_id"] = adoRS.Fields("user_id").Value;
rec_obj["date_corrected"] = adoRS.Fields("date_corrected").Value;
rec_obj["tot_ent"] = adoRS.Fields("tot_ent").Value;
master_arr.push(rec_obj);
adoRS.MoveNext;
i++;
}

is there a way to use newlines in xdmp.eval()

Hi I want to write clean code that I can read and have a good overview.
So I wrote this:
var id = '12345';
var coll = ['scc-roles','scc-proj-' + id];
var spm = 'some-role';
var data = {role : spm, roleNames : 'sccss-user', collection : coll}
var spmRoleId = xdmp.eval('declareUpdate();
var sec = require("/MarkLogic/security.xqy");
var roleId = sec.createRole(role, "Generated project member", roleNames, null, collection,null,null);
var uri = "http://marklogic.com/xdmp/roles/" + roleId;
xdmp.documentAddCollections(uri,collection)',data,{"database" : xdmp.securityDatabase()})
But apparently a newline is not allowed in xdmp.eval() ?
[javascript] JS-JAVASCRIPT: + 'var sec = require("/MarkLogic/security.xqy"); -- Error running JavaScript request: SyntaxError: Unexpected token ILLEGAL
I tried using a '+' sign to generate a strng over more then one line, swapping single and double quotes but no luck.
Being able to test this code (copy paste) to the security database makes a lot of sense to me...
If I wrap it all in one unreadable line , it works ok.
hugo
The way to effectively create a new line in a JavaScrit string is to escape the new line char like this
var str = "I'm displayed\
in two line";
In the final file, you will see effectively a new line.
If you want see in the dist output the new line but not in your src string you could just insert the \n equivalent of a return to line.
var str = "I'm displayed\n in two line";
In es6 you will be able to use ` char to achieve the same thing without \
var str = `I'm displayed
in two line`;
Maybe you would like the strange, yet useful array-notation way of doing this:
var multiline1 = [
'the lazy fox',
'jumped over',
'the dead chicken',
].join('\n');
and the result:
the lazy fox
jumped over
the dead chicken
In general, you should avoid string concatenation to build code for eval. Strings make it difficult to spot bugs and are a great vector for injection attacks. Instead, I'd advise you to write a proper function in XQuery or JavaScript and use xdmp.invokeFunction to evaluate it. invokeFunction takes all of the same options as xdmp.eval.
Here's an example that gets roles in the context of a security database. The applyAs function returns a function that wraps the function provided by the caller, evaluating it with the eval options provided.
function applyAs(fct, options) {
return function() {
var params = Array.prototype.slice.call(arguments);
// Curry the function to include the params by closure.
// xdmp.invokeFunction requires that invoked functions have
// an arity of zero.
var f = (function() {
return fct.apply(null, params);
}).bind(this);
// Allow passing in user name, rather than id
if(options.user) { options.userId = xdmp.user(options.user); delete options.user; }
// Allow the functions themselves to declare their transaction mode
if(fct.transactionMode && !(options.transactionMode)) { options.transactionMode = fct.transactionMode; }
return xdmp.invokeFunction(f, options); // xdmp.invokeFunction returns a ValueIterator
}
}
/**
* Gets an Array of id-name Objects. Requires privileged access to security.
*
* #param names An optional Array of role IDs as strings used to filter
* #return An Array of Objects with role ID keys and role name values
*/
function getRoles(names) {
var sec = require('/MarkLogic/security.xqy');
var db = {database: xdmp.securityDatabase()};
var roleIDs = applyAs(sec.getRoleIds, db);
var rolesItr;
if(Array.isArray(names)) {
rolesItr = roleIDs(xdmp.arrayValues(names));
} else {
rolesItr = roleIDs();
}
var roleNames = applyAs(sec.getRoleNames, db)(rolesItr).toArray().map(function(el) { return el.textContent; });
var roles = [];
var i = 0;
for(var role of rolesItr) {
var r = {}
r[role.textContent] = roleNames[i++];
roles.push(r);
}
return roles;
}
getRoles();
Originally from a gist.

How do I overwrite object properties in an array?

I would like to overwrite a certain allOrders[i] with data, similar to how I create a new one. For some reason I can't figure out what to search on.
I have an array of objects allOrders.
I have an object BusinessCard. I take the form fields, serialize() them, clean up the data with a regex, then push the them into an array.
allOrders.push(new BusinessCard(currentOrder.quantity, currentOrder.FullName, currentOrder.Title, currentOrder.CellNumber, currentOrder.OfficeNumber, currentOrder.FaxNumber, currentOrder.EmailAddress, currentOrder.Address, currentOrder.website, currentOrder.price));
I've tried searching for overwriting existing object properties in an array and the likes and haven't figured out what to do here.
My best guess was allOrders[i].push -- but it seems to me that I have to write a new function to replace each property in the object.
Right now I am using(because using serialize() on the form inputs doesn't help me at all:
allOrders[i].quantity = $('#bcQuantity').val();
allOrders[i].fullname = $('#fullName').val();
allOrders[i].title = $('#Title').val();
allOrders[i].cell = $('#CellNumber').val();
allOrders[i].office = $('#OfficeNumber').val();
allOrders[i].fax = $('#FaxNumber').val();
allOrders[i].email = $('#EmailAddress').val();
allOrders[i].address = $('#Address').val();
allOrders[i].website = $('#website').val();
allOrders[i].price = $('#bcCostBeforeCart').text();
There has to be a smarter way to do this. Thank you.
EDIT:
function getFormData(formId) {
var currentForm = '#' + formId;
var currentPrice = $('#bcCostBeforeCart').text();
var currentFormData = $(currentForm).serialize();
var currentFormDataFinal = currentFormData + '&price=' + currentPrice;
return JSON.parse('{"' + decodeURI(currentFormDataFinal.replace(/\+/g, " ").replace(/&/g, "\",\"").replace(/=/g, "\":\"")) + '"}');
}
MEANING i could be using
currentOrder = getFormData('businessCardForm');
then
allOrders[i] = currentOrder;
Seems odd that you would be updating all items with the selector's you're using, but I would wrap up getting the updated order information then, you can run thru a loop.
Depending on your output, as long as it's outputing the respective properties and values of an order object you could just do:
for(int i =0; i < allOrders.length; i++){
var currentFormId = '' // update this for each iteration.
allOrders[i] = getFormData(currentFormId);
}
allOrders[i] = getUpdatedOrder();
function getUpdatedOrder() {
var order = {};
order.quantity = $('#bcQuantity').val();
order.fullname = $('#fullName').val();
order.title = $('#Title').val();
order.cell = $('#CellNumber').val();
order.office = $('#OfficeNumber').val();
order.fax = $('#FaxNumber').val();
order.email = $('#EmailAddress').val();
order.address = $('#Address').val();
order.website = $('#website').val();
order.price = $('#bcCostBeforeCart').text();
return order;
}

Categories