Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I want to access same variable properties in a java script file but because are too many properties the code looks a bit to ugly. I have the next code:
$scope.invoice = new Invoice();
$scope.operations = {
editingLine: {},
isNewLine: false,
isEditOpen: false
};
$scope.modify = function (invoiceLine) {
if ($scope.operations.isEditOpen) return;
let originalLine = $scope.invoice.invoiceLines.find(line => line.id = invoiceLine.id);
tempLine = angular.copy(originalLine);
$scope.operations.editingLine[invoiceLine.id] = true;
$scope.operations.isEditOpen = true;
};
Is there any way to access the the property invoiceLine which is set on the object invoice, or the property isEditOpen which is set on the object operations in cleaner way? I have a lot of repetition of this code in my file and I want to find a clener way to access properties like this.
I know that I can to define a variable var operations = $scope.operations and to access the property operations.isEditOpen when I need this value but still, I want something more simpler because I don't want to create variable for all objects from the scope.
Is there any way to create a function with two params (objectFromScope, neededProperty) that can return the requiered property value from a variable which is set on the scope? Or is there any better way to do not have such much code when I want to access an object property from the scope?
PS: I can also do something like this:
let editingLine = $scope.operations.editingLine;
let isNewLine = $scope.operations.isNewLine;
let isEditOpen = $scope.operations.isEditOpen;
$scope.modify = function (invoiceLine) {
if (isEditOpen) return;
let originalLine = invoiceLines.find(line => line.id = invoiceLine.id);
tempLine = angular.copy(originalLine);
editingLine[invoiceLine.id] = true;
isEditOpen = true;
};
But is this a good approach?
Is there any way to create a function with two params ( objectFromScope, neededProperty ) that can return the required property value from a variable which is set on the scope? Or is there any better way to do not have such much code when I want to access an object property from the scope?
Yes, but I don't see how it saves you any trouble. It will also make it harder to switch to TypeScript (though you can make it work with keyof if you don't want to dereference an entire property path).
But this is that function:
function getPropertyValue( objectFromScope, neededProperty ) {
const pathComponents = neededProperty.split( '.' );
let obj = objectFromScope;
for( const component of pathComponents ) {
obj = obj[ component ];
}
return obj;
}
Usage:
$scope.invoice = new Invoice();
$scope.operations = {
editingLine: {},
isNewLine: false,
isEditOpen: false
};
$scope.modify = function( invoiceLine ) {
if ($scope.operations.isEditOpen) return;
const lines = getPropertyValue( $scope, 'invoice.invoiceLines' );
let originalLine = lines.find(line => line.id = invoiceLine.id);
tempLine = angular.copy(originalLine);
$scope.operations.editingLine[invoiceLine.id] = true;
$scope.operations.isEditOpen = true;
};
...but this really doesn't make your code any easier to read or maintain. Instead it makes it worse because doing things this way is very non-idiomatic for JavaScript and AngularJS: anyone else who works on this project will stare at the code for a few minutes and scratch their head before wondering out loud why you're doing this in the first place.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 15 days ago.
Improve this question
I want to check the result of a function with sum of two numbers without having a return statement:
function sum(a,b){
var res = a+b;
return true;
}
test('sum of numbers', () => {
expect(sum(1,2)).toBe(res)
});
How to get the value of the res variable in my test?
The test should be testing the result of the function. You can not access variables inside of a function since the varaibles scope is to the function block and it is not global.
You function should be returning the result from the function and your test should be testing what you expect the output to be.
function sum(a,b){
var res = a + b;
return res;
// return a + b;
}
test('sum of numbers', () => {
expect(sum(1,2)).toBe(3)
});
Testing implementation details like this is an anti-pattern in regards to frontend testing. You should be testing the user interaction that calls this function (eg. a button click). Then, check whether the rendered text on the screen is your desired result (ex. 1+1=2).
Project requirements that dictate a function is tested directly, are quite simply wrong.
Basic test case for your sum function
test('sum of numbers', () => {
expect(sum(1,2)).toBe(3)
});
or you can use toEqual at the place of toBe.
Even you can check this post https://jestjs.io/docs/getting-started.
I have a few suggestions for you. To get the res value, you can try using a reference type like a JavaScript object.
function sum(a,b, obj){
var res = a+b;
obj.res = res;
return true;
}
test('sum of numbers', () => {
let obj = {};
expect(sum(1, 2, obj)).toBe(true)
expect(obj.res).toBe(5);
});
OR
Another option is to return an object from the function, which would include the boolean value you need to test, along with the internal variable.
function sum(a,b){
var res = a+b;
return {
res,
val: true
};
}
test('sum of numbers', () => {
const {res, val} = sum(2, 3);
expect(val).toBe(true)
expect(res).toBe(5);
});
I noticed in one of your comments on a post that you mentioned
Its a requirement in my project. I have to test an internal variable value inside a function
Just double checking, is it possible that the requirement is actually asking you to return the local variable and compare it, instead of a boolean? If so, you can follow the method outlined in #epascarello's answer. Hope that helps!
I have a question regarding Node.js that I started using recently and I don't have much dexterity yet.
So, I have a function inside the pages.js file and I need some values to be passed to HTML in the same way that was done with "arrayOfCookies", (passing to the router that is also in pages.js). However what I understood is that the function needs to return next () for the page to be loaded. Is there any way to pass these values (7 variables) to the router.get in a similar way to what I have already done with cookies? My goal is to display those in my HTML. I appreciate any help, my code is below - Im not going to put my function here cause i guess its not relevant to answer my question.
router.get('/userPage',beforeReq,authFunct,(req,res) =>{
var arrayOfCookies = req.cookies['myEmail'];
///exercises1,exercises2,exercises3,exercises4,exercises5,exercises6,exercises7 are the variables that i need to pass from my function to the line below. They are all arrays
res.render('userPage', {name: arrayOfCookies})
And this is just a part of the function that I want to pass the values of
function beforeReq(req,res,next){
var allExercises = []
var exercises1 = []
var exercises2 = []
var exercises3 = []
var exercises4 = []
var exercises5 = []
var exercises6 = []
var exercises7 = []
return next()
}
This seems like a very basic question. But how do I create a class structure within Google Apps Script?
Lets say I want to call: myLibrary.Statistics.StandardDeviation(). I have to instead call: myLibrary.StandardDeviation().
I cannot seem to break it down any further, or organize it into classes.
How can I do this?
I suspect there's something more that you're not telling us about your situation. It is possible to set up a function as a property of an object that is itself a property of an object, and thus support the calling structure you've described.
function test() {
Logger.log( myLibrary.Statistics.StandardDeviation([5.3,5.2,5,2.0,3.4,6,8.0]) ); // 1.76021798279042
};
myLibrary.gs
var myLibrary = {};
myLibrary.Statistics = {}
myLibrary.Statistics.StandardDeviation = function( array ) {
// adapted from http://stackoverflow.com/a/32201390/1677912
var i,j,total = 0, mean = 0, diffSqredArr = [];
for(i=0;i<array.length;i+=1){
total+=array[i];
}
mean = total/array.length;
for(j=0;j<array.length;j+=1){
diffSqredArr.push(Math.pow((array[j]-mean),2));
}
return (Math.sqrt(diffSqredArr.reduce(function(firstEl, nextEl){
return firstEl + nextEl;
})/array.length));
}
This question already has answers here:
Is JavaScript a pass-by-reference or pass-by-value language?
(33 answers)
Closed 7 years ago.
I know I am doing something egregiously wrong in using the namespaces. I am posting this question after researching a ton in the net / google searches. Still can’t find what I am doing wrong. Can you please help me out?
This is what I have
Javascript
Javascript file1
(function (js_namspace1, $, undefined) {
js_namespace1.n1function1 = function(){
var return_obj = {
return_function_to_call: “n1function_name2”
return_function_to_call_namespace: “js_namespace1”
}
js_namespace2.n2function1(return_obj)
}
Js_namespace1.n1function_name2 =function(list_of_names){
Js_namespace1.list_of_names = list_of_names
// do some processing to js_namespace1. list_of_names
}
}
(window. js_namspace1 = window. js_namspace1|| {}, jQuery ));
Javascript file2
(function (js_namspace2, $, undefined) {
js_namespace2.n2function1(return_obj) = function(return_obj){
js_namespace2.return_function_to_call = return_obj.return_function_to_call
js_namespace2.return_function_to_call_namespace = return_obj. .return_function_to_call_namespace
// do some processing
Js_namespace2.list_of_names = []
Js_namespace2. list_of_names.push(value_name)
window[js_namespace2.return_function_to_call_namespace][js_namespace2.return_function_to_call]( Js_namespace2.list_of_names);
}
}
(window. js_namspace2 = window. js_namspace2|| {}, jQuery ));
Html
From html file1 call js_namespace1.n1function1 based on end user clicking a field
// js_namespace1.n1function1 calls js_namespace2.n2function1 and displays another html file2
// In html file2 process the data (collect value of names) and then call the return function Js_namespace1.n1function_name2
In Js_namespace1.n1function_name2, process Js_namespace1.list_of_names(array), but when I do this, it also changes in Js_namespace2.list_of_names
For example when I do
Js_namespace1.n1function_name2.push(add_another_name), and then call js_namespace1.n1function1 (which in turn calls js_namespace2.n2function1). Js_namespace2.list_of_names contains the value of add_another_name.
Please note that when js_namespace2.n2function1 is called from js_namespace1.n1function1 the array is not passed as parameter.
My expectation was when js_namespace1.n1function1 calls js_namespace2.n2function1 it would not update Js_namespace2.list_of_names with the add_another_name.
Can you please explain what is happening? most importantly point out any mistakes that I should be avoiding in this design (namespace, exchange of parameters between function calls). Am I using the namespace correctly in javascript – any best practices to recommend?
Here's a link from a quick Google search on best practices for JS. There are different schools of thought out there (eg. use of terminating semicolons), but use of a some kind of linter might help you figure out typos, case sensitivity, and unintended whitespace in the code if you can't notice for yourself. Below is your code with some fixes:
(function (js_namespace1, $, undefined) {
js_namespace1.n1function1 = function(){
var return_obj = {
return_function_to_call: "n1function_name2",
return_function_to_call_namespace: "js_namespace1"
};
js_namespace2.n2function1(return_obj)
};
js_namespace1.n1function_name2 =function(list_of_names){
js_namespace1.list_of_names = list_of_names;
console.log(js_namespace1.list_of_names); // ["some_name"]
};
}
(js_namespace1 = window.js_namespace1 || {}, jQuery));
(function (js_namespace2, $, undefined) {
js_namespace2.n2function1 = function(return_obj){
js_namespace2.return_function_to_call = return_obj.return_function_to_call;
js_namespace2.return_function_to_call_namespace = return_obj.return_function_to_call_namespace;
// do some processing
js_namespace2.list_of_names = [];
js_namespace2.list_of_names.push("some_name");
window[js_namespace2.return_function_to_call_namespace][js_namespace2.return_function_to_call]( js_namespace2.list_of_names);
};
}
(js_namespace2 = window.js_namespace2 || {}, jQuery));
js_namespace1.n1function1();
Some points about your code and my fixes:
You used case sensitive names like js_namespace2 for Js_namespace2.
Your syntax here is incorrect js_namespace2.n2function1(return_obj) = function(return_obj).
And here: return_obj. .return_function_to_call_namespace and others.
value_name is not defined
I tested the code here and see expected behavior.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I want to store into an array, a set of closures to be run when it been called.
Is eval the best thing to do it?
"Eval is evil" ;-)
but here's a possible solution
Array.prototype.execute = function() {
for ( var i in this ) {
if ( i && 'execute' != i && Function == this[ i ].constructor ) {
this[ i ].apply( this );
}
}
};
var arr = [];
arr.push( ( function() {alert('A'); } ) );
arr.push( ( function() {alert('B'); } ) );
arr.push( ( function() {alert('C'); } ) );
arr.execute();
please keep in mind: it's not recommended to extend basical Javascript types in the way I did.
I’m not sure what you mean by "run when it been called", but since Arrays are Objects, you can store static information as object keys in the array:
var arr = ['foo','bar'];
arr.methods = {
foo: function() { alert(this[0]); },
bar: function() { alert(this[1]); },
};
arr.run = function() {
for (var fn in this.methods) {
this.methods[fn].call(this);
}
};
arr.run();
You could also make this into a reusable function using prototypal inheritance, but you would need to embed the array inside it, since Arrays are not "subclassable" in javascript.
Ok, since everybody keeps guessing at what it is you're actually looking for, here's my .02:
var closures = (function(Global,undefined)
{
var that = [];//return value
that[0] = (function(some,vars, forClosure1)
{
return function()
{
console.log(some, vars,forClosure1);
};
})(values,of,closureArguments);//create all closures you need
that.execAll = function (context,args)//the method to call them all (with arguments)
{
context = (context === undefined || context === Global ? that : context);
args = args.length ? args : [];//make sure arguments has length property
for (var i=0;i<that.length;i++)
{
if (typeof that[i] === 'function')
{
that[i].apply(context,args);
}
}
};
return that;//return closure array (with execAll method)
})(window);
Now, I've created an array of closures, that has its own method execAll, you can pass 2 arguments to this method: the first determines the context in which the closre functions of the array will be called, the second expects an array or arguments object to pass to each of these closure functions.As it currently stands, the closures cannot be called in a global context using execAll. That's just for safety, but you never know, maybe you might want to call them in the global object's context.
All in all, I think this is what you're looking for, though I must admit: I'm struggeling to see how this code could be of any use, but maybe that's just me.Anyway: good luck
You can create a function on the fly and store the reference in a variable:
var something = function() { alert("hello world"); };
And by extension in an array:
var something = [function() { alert("hello world"); },
function() { alert("hello world"); },
function() { alert("hello world"); }];
Which you may later call by using something(); in the first example or something[1](); in the second for instance. Eval is absolutely not needed here, unless the actual body of the function comes from user input (god forbid :-) )
What and how to call it is left to the implementation, but it should be fairly trivial once you are aware of this.