Set Function name as String - Javascript - javascript

Hey I'm trying to create a String Const with the value of the function wrapping it
Const url = 'mainapiurl.com/api/'
export function GetPointsStoreBenefits() {
const urlExtention = // I want to name it automatically like the function (GetPointsStoreBenefits)//
FullUrl = url + urlExtention
I need to make a lot of calls so I was wondering is it the best practice? any suggestions?
the concept supposed to be dynamic code like this
const urlExtention = thisfunction.name

The easiest option is to make a higher order function that you can derive your other functions from:
const url = 'mainapiurl.com/api/'
function makeFunction(urlExtention) {
return function() {
const fullURL = url + urlExtention;
/* do something */
console.log("full URL is:", fullURL);
}
}
/* export */ const GetPointsStoreBenefits = makeFunction("GetPointsStoreBenefits");
/* import GetPointsStoreBenefits ... */
GetPointsStoreBenefits();

Function object have a name property, which contains the function name.
So in your case you can do something like:
export function GetPointsStoreBenefits() { }
const urlExtention = GetPointsStoreBenefits.name;
See also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name

Related

Javascript New Function - Best way to pass large number of functions as parameter

In angular project and learning to build a feature to run a custom script using the new function method. With the great help from this forum I have been able to come up with core script solution.
The question I have if I have a large number of custom functions I need to pass into New Function to access what would be the best method?
So far I have 2 options:
Option 1.
Passing each function as parameter. My concern if there is 50 plus function this could look messy.
eg
const userFunction = new Function('testFunc1','testFunc2','testFunc3'...'testFunc50', script);
Option 2.
Nest the functions in parent function. The draw back is to access the function we need to call the parent function which again can look messy in the code writing. Eg
parentFunc().nestFunc().
Question is there a better way to do this?
Code and stackblitz below.
https://stackblitz.com/edit/angular-bx5kia?file=src/main.ts
option1() {
var nestFunc1 = () => {
alert('Nest1');
};
var nestFunc2 = () => {
alert('Nest2');
};
const script = `
var value = 1 +4;\n
console.log('value',value);\n
nestFunc1();\n
console.log("End Script");\n
`;
const userFunction = new Function('nestFunc1', 'nestFunc2', script);
userFunction(nestFunc1, nestFunc2);
}
option2() {
const script = `
var value = 1 +4;\n
console.log('value',value);\n
parentFunc().nestFunc2();\n
console.log("End Script");\n
`;
var parentFunc = (msg?: string) => {
console.log('Test Function', msg);
var nestFunc1 = () => {
alert('Nest 1');
};
var nestFunc2 = () => {
alert('Nest 2');
};
return { nestFunc1, nestFunc2 };
};
const userFunction = new Function('parentFunc', script);
userFunction(parentFunc);
}
Well, I'm not an expert with Angular but as we are working with JS maybe I can give you some light in plain JS and then you can convert it to Angular syntax.
In JS you can write functions inside an array:
const functions = [
() => console.log( 'Nest 1' ),
() => console.log( 'Nest 2' )
]
And then, in your userFunction you can make a loop inside this array calling all functions:
const userFunction = ( functionsArray ) => {
functionsArray.forEach( nestedFunction => nestedFunction() )
}
Hope I can give you any idea :)

How to programmatically add a function to an Object like the following example

How to programmatically add an Object method like the following example.
let object2 = {
name: "object2",
onExecute() {
const input1 = this.getInputData(0)
// do something
}
}
I'm trying to figure out how to programmatically add a method to the object. I need to end up with the object2 example.
I tried the following, but it does not seem to be correct.
object2.onExecute = () => {
const input1 = this.getInputData(0)
// do something
}
In the end I did this:
object2.onExecute = function () {
const input1 = this.getInputData(0)
// do something
}
and it worked as expected.

String with a variable that can be replaced (php's sprintf equivalent)

I have a class that looks like below
interface IParams: {
academicYearId: number;
// Other Params
};
export class myClass() {
function1() {
const url = `api/accounts/academic-year/${academicYearId}/financial-plan`;
// Function 1 Functionality
}
function2() {
const url = `api/accounts/academic-year/${academicYearId}/financial-plan`;
// Function 2 Functionality
}
function3() {
const url = `api/accounts/academic-year/${academicYearId}/financial-plan`;
// Function 2 Functionality
}
}
To reduce on the repetition I made url a property
interface IParams: {
academicYearId: number;
// Other Params
};
export class myClass({academicYearId}: ) {
url = `api/accounts/academic-year/:id/financial-plan`;
urlWithId = (academicYearId: number) => this.url.replace(':id', academicYearId )
function1() {
const url = this.urlWithId(academicYearId)
// Function 1 Functionality
}
function2() {
const url = this.urlWithId(academicYearId)
// Function 2 Functionality
}
function3() {
const url = this.urlWithId(academicYearId)
// Function 2 Functionality
}
}
The above approach works but am I was wondering if there is a better way I can approach the below two lines other than setting a part of the string to ':id' and then replace that part with the id value. Something like in php's sprintf
url = `api/accounts/academic-year/:id/financial-plan`;
urlWithId = (academicYearId: number) => this.url.replace(':id', academicYearId )
String interpolation
It's a common approach for doing that like below:
urlWithId = (academicYearId) => `api/accounts/academic-year/${academicYearId}/financial-plan`;

Javascript (ES6), destructure based off variable

I am wondering to see if there is a way to destructure objects in javascript with using a variable. Where as I was doing something like this in my function -
mutateTaxon(data) {
const { content } = data;
const { plp } = content || {};
...
This was working fine, however I need to expand this function based off another factor that can change if I need to use data.content (which it is using now) or data.collection. So I have another node on the data - which changes call to call. I am trying something like this -
mutateTaxon(data) {
const match = lowerCase(data.taxonomy.name);
const { match } = data;
const { plp } = match || {};
Where that match variable would evaluate to either content or collection (as expected). This does not seem to work however, maybe it is not possible? I was thinking maybe the match var needed to be evaluated so I tried something like -
const { [[match]] } = data;
which also is not working. Maybe this is not possible, or I am approaching this wrong. I am wondering, is something like this possible? Thanks!
The destructuring syntax would, as Jonas W. said, be a bit more cumbersome than the bracket notation, but nonetheless, this is how you would do it:
mutateTaxon(data) {
const key = lowerCase(data.taxonomy.name);
const { [key]: { plp } = {} } = data;
Demo
const foo = { bar: { plp: 'success' } }
const key = 'bar'
const { [key]: { plp } = {} } = foo
console.log(plp)
And to confirm that default parameter = {} works as expected:
const foo = { }
const key = 'bar'
const { [key]: { plp } = {} } = foo
console.log(plp)
const key = lowerCase(data.taxonomy.name);
const match = data[key];
I dont think that object destructuring is useful here. But if you need that:
const key = lowerCase(data.taxonomy.name);
const {[key]: match} = data;

calling function within module that is imported to another class

I am new to JavaScript (working my way through some basic tutorials). Can someone tell me what I am doing wrong here? I am trying to get the run function to reference the withinCircle function, then export the whole thing to another file so I can reference the run function. Feel free to modify my code anyway you want- I tried to follow "best" practices but I may have screwed up. Thanks!
var roleGuard = {
/** #param {Creep} creep **/
run: function(creep)
{
var target = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {filter: { owner: { username: 'Invader' } }});
if(target!=null)
{
console.log(new RoomPosition(target.pos.x,target.pos.y,'sim'));
//ranged attack here
//within 3, but further than 1
if(creep.pos.getRangeTo(target)<=3&&creep.pos.getRangeTo(target)>1)
{
creep.rangedAttack(target);
console.log("ranged attacking");
}
}
else
{
var pp=withinCircle(creep,target,3,'sim');
console.log(pp);
creep.moveTo(pp);
}
}
//------------------------------------------------------------
//move to closest point within z units of given evenmy
withinCircle: function(creep,target,z,room)
{
var targets = [new RoomPosition(target.pos.x-z,target.pos.y-z,room), new RoomPosition(target.pos.x+z,target.pos.y-z,room),new RoomPosition(target.pos.x-z,target.pos.y+z,room),new RoomPosition(target.pos.x+z,target.pos.y+z,room)];
var closest = creep.pos.findClosestByRange(targets);
return(closest);
}
//------------------------------------------------------------
};
module.exports = roleGuard;
Other file contains:
var roleGuard = require('role.guard');
for example:
// foo.js
function add(a,b){
return a + b
}
module.exports = add
and in the other file:
// bar.js
const add = require("./foo");
console.log(add(1,1))
those paths are relative to the file location. extension can be omitted.
you'll need node or browserify or webpack to make exports/require to work properly.
if you want a better explanation about modular javascript, look there, even if you not enter in the browserify world it will present you to what we can do nowadays.
EDIT:
in order to export more symbols you can do the following:
// foo2.js
function add(a,b){
return a + b
}
function multiply(a,b){
return a * b
}
module.exports = {
add:add,
multiply:multiply
}
And then in the consumer:
// bar2.js
const add = require("./foo2").add
const multiply = require("./foo2").multiply
//...
This is also valid:
// foo3.js
function add(a,b){
return a + b
}
exports.add = add
function multiply(a,b){
return a * b
}
exports.multiply = multiply
Consumer will need no relevant alteration:
// bar3.js
const add = require("./foo3").add
const multiply = require("./foo3").multiply
//...
If using babel/es6 modules have a different idion, which you can check there.

Categories