I am new to javascript, i trying to learn to js, here i am getting syntax error while console the output
const screemwarriors = () => {
var warriors = "Ninja";
shootwarriors = function(){
console.log(warriors);
}
}
const output = screemwarriors();
console.log(output.shootwarriors());
Here i am getting syntax error
Looks like your trying to access the result as an object. You must return the function in an object if you intend to do it in this way.
Update: cleaned up code
const screemwarriors = () => ({
shootwarriors: () => {
console.log("Ninja");
}
});
const output = screemwarriors();
output.shootwarriors();
Cheers,
Your calling code will work if you modify your function like this:
const screemwarriors = function() {
var warriors = 'Ninja';
return {
shootwarriors: function() {
return warriors;
}
}
}
const output = screemwarriors();
console.log(output.shootwarriors());
Related
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 :)
I'm tried to something like : Catch all events in my addEventListeners and then call my function calculateBill. I have a problem my events are lost. It is possible to pass the parameters for each addeventlister separately. I try to do it since few hours and i have no idea what's happening here.
const billInput = document.querySelector('#bill');
const percentageButton = document.querySelectorAll('.tip__values--item');
const numberOfPeople = document.querySelector('#people');
const tipAmount = document.querySelector('.result__amount--price');
const totalBill = document.querySelector('.result__total--price');
const reset = document.querySelector('button');
const catchBill = (e) => {
return e.target.value;
};
const catchPeople = (e) => {
return e.target.value;
};
const handleButtons = (e) => {
return e.target.textContent;
};
const calculateBill = (catchBill, catchPeople, handleButtons) => {
console.log(
'catchBill:',
catchBill,
'catchPeople:',
catchPeople,
'handleButtons:',
handleButtons
);
};
billInput.addEventListener('keyup', function (e) {
calculateBill(catchBill(e), catchPeople, handleButtons);
});
numberOfPeople.addEventListener('keyup', function (e) {
calculateBill(catchBill, catchPeople(e), handleButtons);
});
percentageButton.forEach((btn) => {
btn.addEventListener('click', function (e) {
calculateBill(catchBill, catchPeople, handleButtons(e));
});
});
I know that i can do this FrontedMentor challenge in other way but I'd like to know is this possible to do it that way. I know that problem is with parameters that i call in addeventlistener. How can i get my parameters in my calculateBill function with all events?
You'll need to cache the result of each event somewhere so that you can retrieve them later, or retrieve the value in every input each time any event takes place. It looks like calculateBill expects arguments to be strings, not functions, so passing catchBill, catchPeople, or handleButtons (which are functions) to it doesn't make sense. Consider something like:
// assign default values here if you want
let billValue;
let numPeople;
let percValue;
const handleBillChange = (e) => {
billValue = e.target.valueAsNumber;
calculateBill();
};
const handlePeopleChange = (e) => {
numPeople = e.target.valueAsNumber;
calculateBill();
};
const handlePercentageChange = (e) => {
percValue = e.target.textContent;
calculateBill();
};
billInput.addEventListener('keyup', handleBillChange);
numberOfPeople.addEventListener('keyup', handlePeopleChange);
billInput.addEventListener('keyup', handleBillChange);
// This is a NodeList, not a button. Consider naming the variable more precisely.
// percentageButtons, perhaps?
percentageButton.forEach((btn) => {
btn.addEventListener('click', handlePercentageChange);
});
While it'd be technically possible to store the previous events instead, and then do something like
billInput.addEventListener('keyup', function (e) {
calculateBill(catchBill(e), catchPeople(previousPeopleEvent), handleButtons(previousButtonEvent));
});
for all the inputs and buttons, that'd be extremely strange. Better to store just the values.
I have the CalculationDesignSingleton.js file, and the CalculationDesignSingleton.test.js which is using Jest to test the file. When I run the test file, I received an error said calculation.getInstance is not a function. Can someone help me? Thank you
CalculationDesignSingleton.js
let calculation = (function () {
let instance;
function createInstance() {
let calculator = new Calculator("I am the instance");
return calculator;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
CalculationDesignSingleton.test.js
const calculation = require('../src/Operations/CalculationDesignSingleton');
test('Test Design Pattern Singleton of Calculation', () => {
//I need to test the get results function
const singletonA = calculation.getInstance();
const singletonB = calculation.getInstance();
const isEqual = singletonA === singletonB;
expect(isEqual).toBe(true);
});
I want to write a babel plugin that blocks global variables such as document and xhr from part of the code。
But I don't know how to tell if it belongs to window.
Example:
function queryClass(name){
return document.querySelector(`.${name}`);
// or return window.document.querySelector(`.${name}`)
}
I hope it turns into this
function queryClass(name){
return noDocument.querySelector(`.${name}`);
// or return window.noDocument.querySelector(`.${name}`)
}
But I don't want this code to be converted:
const document = {querySelector(str){return str + '1'}}
function queryClass(name){
return document.querySelector(`.${name}`);
// or return obj.document.querySelector(`.${name}`)
}
So I think I should learn to judge if it's a global variable.
Or is there any other way to help me achieve this?
This is my simple babel code:
const babel = require("#babel/core");
const code = `
function queryClass(name){
return window.document.querySelector(\`.\${name}\`);
}
`;
const visitor = {
Identifier(path) {
if(path.isIdentifier({name: 'document'})){
// How to judge if it's a global variable
path.node.name = 'noDocument';
}
}
}
const result = babel.transform(code, {
plugins: [{visitor}]
});
I just find a way to do this.
I don't know if it's a good idea.
const babel = require("#babel/core");
const code = `
function queryClass(name){
return window.document.querySelector(\`.\${name}\`);
}
`;
const updateParamNameVisitor = {
Identifier(path) {
if (path.node.name === this.from) {
path.replaceWith(this.to);
}
}
};
const visitor = {
Program(path){
if(path.scope.globals.document){
const node = path.scope.generateUidIdentifier('no_document');
path.traverse(updateParamNameVisitor, { from: 'document', to: node })
}
}
}
const result = babel.transform(code, {
plugins: [{visitor}]
});
I'm new to babel plugin too
I think that is the way:
// inside Identifier(path)
const binding = path.scope.getBinding('document')
if (!binding) {
// global
} else {
// declaration point
console.log(binding.identifier.loc)
}
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;