Passing Arguments to function in javascript - javascript

I have a function(case) as below,
let fn = (() => {
let ab = {};
let register = () => {
console.log("hello" + ab[x])
};
return (x,y) => {
ab[x] = y;
return register();
};
})();
this function is working only when I call as below,
let x = 'key';
let y = 'value';
fn(x,y);
Is there any chance to call directly like
fn('key', 'value');
what changes I have to make in function to call directly

The problem is your register function doesn't know about x. You need to pass it through from your previous function:
let fn = (() => {
let ab = {};
let register = (x) => {
console.log("hello" + ab[x])
};
return (x,y) => {
ab[x] = y;
return register(x);
};
})();
fn("key", "value");

I believe this is because you aren’t defining the parameters in the functions.
let fn = ((x,y) => {
let ab = {};
let register = () => {
console.log("hello"+ab[x])};
return (x,y) => {
ab[x]=y;
return register();
};
})();

Related

How to overwrite a variable in a dynamic way and not in a hardcoded way?

I have something similar to this code:
addBlock = document.querySelectorAll(`[slide='B.slide1'] .TEAM`);
addBlock = addBlock[addBlock.length - 1];
function addNewSimilarBlockOfCode(x) {
HTML = x.outerHTML;
//insert new block of code after the previous one:
x.insertAdjacentHTML('afterend', HTML);
//redeclare x with the new added HTML code
x = x; // here is the problem. this is an incorrect code!
console.log('the new value of x is: ' + x);
}
addNewSimilarBlockOfCode(addBlock);
as you can see the problem is that the new x is still indicating the one in the argument which was the old value of x.
I need a dynamic way to implement this, I don't want to hardcode it, some people might say "instead of writing x = x, write instead:
x = document.querySelectorAll(`${slide('B.slide1')} .TEAM`);
x = addBlock[x.length - 1];
The problem is I don't want to hardcode it.
The original code I have, it is currently working, but I want to change it from being a hardcoded function (the addField and the newField functions) to be dynamic so I can use them later:
const UI = (() => {
//TOOLS:
const $ = (x) => document.querySelector(x);
const $$ = (x) => {
let element = document.querySelectorAll(x);
element = slice_array(element);
return element;
};
const slice_array = (x) => {
return Array.prototype.slice.call(x);
};
const slide = (path) => {
path = path.split(".");
return `[scope='${path[0]}'][slide='${path[1]}']`;
};
//-------------</TOOLS>
const addField = (element, replace) => {
let HTML;
console.log("replace this: " + replace[0] + " with this: " + replace[1]);
HTML = element.outerHTML;
if (replace instanceof Array)
HTML = element.outerHTML.replace(replace[0], replace[1]);
element.insertAdjacentHTML("afterend", HTML);
};
return {
addField: addField,
};
})();
const controller = ((UI, model) => {
//TOOLS:
const $ = (x) => document.querySelector(x);
const $$ = (x) => {
let element = document.querySelectorAll(x);
element = slice_array(element);
return element;
};
const slice_array = (x) => {
return Array.prototype.slice.call(x);
};
const slide = (path) => {
path = path.split(".");
return `[scope='${path[0]}'][slide='${path[1]}']`;
};
//-------------</TOOLS>
let addBlock;
addBlock = $$(`${slide("B.slide1")} .TEAM`);
const eventList = () => {
addBlock[addBlock.length - 1].addEventListener("input", newField);
};
let newField = () => {
let replaceThis, withThis;
addBlock = $$(`${slide("B.slide1")} .TEAM`);
replaceThis = `<span id="TEAM_NUMBER_${counter}">${counter}</span>`;
withThis = `<span id="TEAM_NUMBER_${counter + 1}">${counter + 1}</span>`;
replace = [replaceThis, withThis];
addField(addBlock, replace);
};
let counter = 1;
const addField = (addBlock, replace) => {
e = window.event;
const target = e.target || e.srcElement;
//remove previous event listener
addBlock[addBlock.length - 1].removeEventListener("input", newField);
console.log(addBlock);
//insert new field
UI.addField(target.parentNode, replace);
counter = counter + 1;
//add new event listener
addBlock = $$(`${slide("B.slide1")} .TEAM`);
addBlock[addBlock.length - 1].addEventListener("input", newField);
};
You can use cloneNode instead of getting outerHtml and appending it. And use x.insertAdjacentElement('afterend', clone); & x = clone;.
Try it below.
var addBlock = document.querySelectorAll(`.slide1 .TEAM`);
addBlock = addBlock[addBlock.length - 1];
function addNewSimilarBlockOfCode(x) {
// pass true as parameter to copy with children nodes
var clone = x.cloneNode(true);
//insert new block of code after the previous one:
// use insertAdjacentElement instead of insertAdjacentHTML
x.insertAdjacentElement('afterend', clone);
//redeclare x with the new clone
x = clone; // here is the problem. this is an incorrect code!
console.log('the new value of x is: ' + x);
}
addNewSimilarBlockOfCode(addBlock);
<div class='slide1'>
<div class='TEAM'>
hello world
</div>
</div>
If you want something to be dynamic, that usually means you want a function to return a value for you.
You can try something like this:
// Gets a live collection of HTML elements
const blocks = document.getElementsByClassName("block");
printLength(blocks);
// Adds more elements and reports the new lengths
addNewBlock(blocks);
printLength(blocks);
addNewBlock(blocks);
printLength(blocks);
// Gets the block that is __currently__ the last one
function getLastBlock(blocks){
const lastIndex = blocks.length - 1;
const lastBlock = blocks[lastIndex];
return lastBlock;
}
// Uses `getLastBlock` to determine where to add more content
function addNewBlock(blocks){
let last = getLastBlock(blocks);
last.insertAdjacentHTML("afterend", last.outerHTML);
last = getLastBlock(blocks); // Now, `last` is the new block
last.insertAdjacentHTML("beforeend", "I"); // To distinguish it from previous block
}
// Reports the current total number of blocks
function printLength(blocks){
console.log(`blocks.length = ${blocks.length}`);
}
<div class="block">Block I</div>
NOTE: The querySelectorAll method returns a static list, so if you use it, you should call it inside your getLastBlock function so that it can retrieve the most recent version.

Javascript Shopping list declaring let

Why this program doesn't work when i try declaring let inputError globally like the rest lets or I write let before inputError in function?
I don't understand why it only works when it is declaring inside the function without let, const.
let ul_var;
let shoppingArray = ["Mleko", "Jajka", "Piwo"];
let new_item_form_var;
>>>> let inputError; <<<< //without it works
document.addEventListener("DOMContentLoaded", () => {
ul_var = document.getElementById("shopping");
>>>> let <<<< inputError = document.getElementById('inputError');
new_item_form_var = document.getElementById("new_item_form");
new_item_form_var.addEventListener("submit", (event) => {
event.preventDefault();
let input = event.target.elements[0];
if (input.value.length > 2 && !input.value.startsWith(' ')) {
addListItem(input.value);
input.value = '';
input.classList.remove('input-danger');
inputError.innerText = '';
} else {
inputError.innerText = 'Nazwa nie spelnia kryteriow';
input.classList.add('input-danger')
}
});
for (let x of shoppingArray) {
addListItem(x);
}
});
function addListItem(y) {
let li_var = document.createElement("li");
li_var.innerText = y;
ul_var.appendChild(li_var);
}
If you have one let inputError then you can't have another one, because you can't declare the same variable several times. You should instead write:
let inputError;
document.addEventListener("DOMContentLoaded", () => {
ul_var = document.getElementById("shopping");
inputError = document.getElementById('inputError'); // no let
or this, if you don't use inputError outside of the event listener:
// no 'let inputError;'
document.addEventListener("DOMContentLoaded", () => {
ul_var = document.getElementById("shopping");
let inputError = document.getElementById('inputError');

Promise not getting resolved

I have problem when calling promise from PO. In PO it works OK but in main test page it gives undefined value. Like function on main page is called before promise is resolved
PO code
this.Email = function (){
this.userIcon.getText(this.userIcon).then(function (text){
this.email=text.slice(5);
console.log(this.email);
return this.email
});
Code in main test page
email = data.Email();
Sorry here is the whole code from PO
var data = function(){
this.user = 'baseer#adnoc.ae';
this.pass = '123123';
this.usrform = element(by.css("input[formControlName=username]"));
this.passinput = element(by.css("input[formControlName=password]"));
this.button = element(by.tagName('button'));
this.text = 'Something smart'
this.dir=Math.floor((Math.random() * 3) + 1);
this.subID;
this.dropdown = element.all(by.css("mat-option"));
this.datepicker = element.all(by.xpath("//mat-datepicker-toggle[#class='mat-datepicker-toggle']"));
this.calendar = element(by.xpath("//div[#class='mat-calendar-header']"));
this.calendar = element(by.xpath("//tbody[#class='mat-calendar-body']"));
this.routeArea;
this.countryOfOrigin = element(by.xpath("//mat-select[contains(#formcontrolname,'countryOfOriginId')]"));
this.countryList = element(by.xpath("//div[#class='select-option-cont']"))
this.userProfileRoute = element(by.xpath("//mat-select[contains(#formcontrolname,'assignToUserProfileId')]"));
this.userIcon=element(by.xpath("//a[#class='mat-menu-item']"));
this.Email = function (){
this.userIcon.getText(this.userIcon).then(function (text){
this.email=text.slice(5);
console.log(this.email);
return this.email
});
};`enter code here`
};
module.exports = new data();
Your code should have been
this.Email = function (){
return this.userIcon.getText(this.userIcon).then(function (text){
this.email=text.slice(5);
console.log(this.email);
return this.email
});
Here is why - if you don't return a value from a function you can't reuse it
let my_func = function (a, b) {
let some_var = a + b
}
let result = my_func(1,2);
console.log(result) // undefined
because you're missing return statement, so if you do
let my_func = function (a, b) {
let some_var = a + b
return some_var
}
let result = my_func(1,2);
console.log(result) // 3
The same happens if you do nested functions
let my_func_one = function (a, b) {
let some_var = a + b
return
}
let my_func_two = (a,b) {
my_func_one(a,b)
}
let result = my_func_two(1,2);
console.log(result) // undefined
that happens because your outer function doesn't return anything, but simply runs inner function. But if you have
let my_func_one = function (a, b) {
let some_var = a + b
return some_var
}
let my_func_two = (a,b) {
return my_func_one(a,b) // return
}
let result = my_func_two(1,2);
console.log(result) // 3

'This' undefined in parsing the xml API using react

I have been trying to make a data from XML clickable in react. This is working in one of the function but gives an error when it is called in an another function.
Shows = Unhandled Rejection (TypeError): Cannot read property 'getAuthArticles' of undefined
I have tried using bind(this). I am already using the arrow functions
getData() {
fetch(`http://export.arxiv.org/api/query?search_query=ti:${'therapy'}&sortBy=lastUpdatedDate&sortOrder=ascending`).then(data=>data.text()).then(str => (new window.DOMParser()).parseFromString(str, "text/xml")).then(data => {
var entry = data.getElementsByTagName("entry");
let elems = []
for(let i=0;i<entry.length;i++){
console.log(entry);
let elem = <div key={i} id={entry[i].getElementsByTagName("id")[0].textContent} onClick={this.handleChange}>{entry[i].getElementsByTagName("title")[0].textContent}</div>;
elems.push(elem);
}
console.log(elems)
this.setState({data: elems});
})
}
/* */
handleChange(evt) {
console.log(evt.target.id)
var res = evt.target.id.split("/");
var id = res[5]
fetch(`http://export.arxiv.org/api/query?id_list=${res[4]}/${id}`)
.then(data=>data.text()).then(str => (new window.DOMParser()).parseFromString(str, "text/xml"))
.then(data => {
var summ = data.getElementsByTagName("summary");
let auth = data.getElementsByTagName("author");
let elems1 = [];
let name = [];
console.log(auth)
for (let i = 0; i < auth.length; i++ ){
console.log(auth[i].textContent);
console.log(auth[i].getElementsByTagName("id"));
let elem1 = <div key={i} id={auth[i].textContent} onClick={this.getAuthArticles.bind(this)}>{auth[i].textContent}</div>;
name += auth[i].textContent;
// elems1.push(elem1);
// console.log(elem1)
}
document.getElementById("demo").innerHTML = summ[0].textContent + name;
// window.history.pushState({}, "page 2", "bar.html");
// this.setState({data: elems1});
})
}
getAuthArticles(evt) {
console.log(evt.target.id)
let auth_name = evt;
fetch(`http://export.arxiv.org/api/query?search_query=${auth_name}`)
.then(data=> data.text()).then(str => (new window.DOMParser()).parseFromString(str, "text/xml"))
.then(data => {
var arti = data.getElementsByTagName("title");
let titles = []
for(let i=0;i<arti.length;i++){
let elem = <div key={i} id={arti[i].getElementsByTagName("id")[0].textContent}>{arti[i].getElementsByTagName("title")[0].textContent}</div>;
titles.push(elem);
}
console.log(titles)
})
}
I see you're using normal function and you missing bind(this) in getData()
onClick={this.handleChange}
// should change to
onClick={this.handleChange.bind(this)}
And make sure you bind(this) for getData()
It will easier with arrow function like
handleChange = (evt) => {}
you don't need to bind(this) for arrow function

Get a reference to a local scope from a function

Let's say I have this code:
// somewhere else
var outFn = (() => {
var local = 5;
var fn = () => { console.log(local); };
return fn;
})();
// I have a reference to outFn
outFn(); // prints 5
How to get a reference to outFn's local scope, that is, how to get a reference to local variable using my reference to outFn?
Don't write the last parentheses :
var outFn = (() => {
var local = 5;
var fn = () => { console.log(local); };
return fn;
}) //(); <-- No need those parentheses
Then :
var localFn= outFn();
localFn() ; // prints 5
If you want to access also to local variable also , attach it to fn like following :
var outFn = (() => {
var fn = () => { console.log(fn.local); };
fn.local = 5;
return fn;
});
Now you can read local :
var localFn= outFn();
localFn.local ; // ===5

Categories

Resources