functions in object literal javascript - javascript

i'm a newbie starting to learn java-script..
const textchanger = function () {
let text = "text that has been changed now"
const picktext = function () {
let element = document.querySelector("h1")
element.textContent = text
return {
callfun: function () {
picktext();
console.log(text);
}
}
}
}
textchanger.fun()
<h1> Getting started </h1>
i'm trying to change the text inside
<h1>Getting started</h1>
but getting the error..
TypeError: textchanger.callfun is not a function
at Object.

It looks like you're experimenting with closures but to do that you need to return the inner function from the function you initially call. You can then assign that returned function to a variable, and then call that.
Here's an example that shows how this works. (The setTimeout is there to show how the same function can be called again with different text, and get a different result.)
// Accept an element, and return a new function
// that accepts some text. `element` will be returned
// along with the inner function so it can be used
function textChanger(element) {
return function (text) {
element.textContent = text;
}
}
// Cache the element
const element = document.querySelector('h1');
// Call `textChanger` with the element as its
// argument, and assign the returned function to
// a variable
const changeText = textChanger(element);
// Call that function with some text
changeText('First text!');
// Call the same function with some different text
setTimeout(changeText, 2000, 'Second text!');
<h1>Getting started</h1>

TextChanger is the function not a plain variable so below code works:
textchanger().callfun()

textchanger is a function, but It doesn't return any thing!
I think you mean this:
const textchanger = function () {
let text = "text that has been changed now";
const picktext = function () {
let element = document.querySelector("h1");
element.textContent = text;
return {
callfun: function () {
picktext();
console.log(text);
}
}
}
return picktext(); // <==== put this line
}
textchanger().callfun();

const textchanger = function () {
let text = "text that has been changed now";
const picktext = function () {
let element = document.querySelector("h1");
element.textContent = text;
return {
callfun: function () {
picktext();
console.log(text);
},
};
};
return picktext(); ==>return picktext() function
};
textchanger(); ==> by calling this the text will be changed

Related

addEventListener returns undefined in Javascript

I want set the addEventListner value to int value,
const stringItem = window.addEventListener("click",(e) => {
const itemTarget = e.target;
const itemParent = itemTarget.parentElement.id;
const strItem = parseInt(itemParent.slice(5));
console.log(strItem);
return strItem;
}, false);
let currentItem = stringItem;
console.log(currentItem);
stringItem return undefined, but I want the strItem to be returned
I want to access the strItem value outside the addEventListener.
How do I do that?
The addEventListener returns undefined as a function (see link). You are passing a function to the addEventListener which gets called whenever you click on the window. The return value of that function will be lost. To be able to use that value outside of the function you will have to do something like this:
let stringItem;
window.addEventListener("click",(e) => {
const itemTarget = e.target;
const itemParent = itemTarget.parentElement.id;
const strItem = parseInt(itemParent.slice(5));
console.log(strItem);
stringItem = strItem;
return strItem;
}, false);
The last two line of your code wouldn't work as they're executed as soon as the eventListener gets added. The currentItem will always be undefined. I would advise you to read more on using callback function in javascript.
The return value of the callback function is discarded. It doesn't make sense to return anything. window.addEventListener doesn't return anything. It doesn't make sense to store the result in a variable stringItem.
You can create a variable outside of the function and store the value in it:
let value = 0;
document.querySelector('#button1').addEventListener("click",(e) => {
++value;
}, false);
document.querySelector('#button2').addEventListener("click",(e) => {
value = 0;
}, false);
document.querySelector('#button3').addEventListener("click",(e) => {
console.log(value);
}, false);
<button id="button1">Increment</button>
<button id="button2">Reset</button>
<button id="button3">Show</button>

How to wrap Javascript function within function expression?

I would like to add a wrapper function to one of my functions to show extra information.
Below is my wrapper function:
var wrap = function(functionToWarp, before) {
var wrappedFunction = function() {
if (before) before.apply(this, arguments);
result = functionToWrap.apply(this, arguments);
return result;
}
return wrappedFunction;
}
var beforeFunc = function(){
// print extra infos before functionToWarp() triggers.
}
and my function _printSth to wrap:
var Printer = function () {
this._printSth = function (input) {
// print something from input...
}
}
Printer._printSth = wrap(Printer._printSth, beforeFunc);
I have tried to wrap Printer._printSth by calling
Printer._printSth = wrap(Printer._printSth, beforeFunc); or similar codes but failed.
How should I declare my _printSth() to be able to be wrapped?
You could write
function Printer() {
this._printSth = function (input) {
// print something from input...
};
this._printSth = wrap(this._printSth, beforeFunc);
}
or
function Printer() {
this._printSth = wrap(function (input) {
// print something from input...
}, beforeFunc);
}
but that's equivalent to simply writing
function Printer() {
this._printSth = function (input) {
beforeFunc(input);
// print something from input...
};
}
Assuming you rather might want to wrap the method on a specific instance, you'd do
const p = new Printer();
p._printSth = wrap(p._printSth, beforeFunc);
Altering a method is done like that:
Printer.prototype._printSth = wrap(Printer.prototype._printSth, beforeFunc);

Call functions inside of another function

I am having a problem calling functions inside a function.
This is the sample code:
<script>
function saveInfo() {
function returnEmail() {
var _e = document.getElementById("email").value;
return _e;
}
function returnName() {
var _n = document.getElementById("name").value;
return _n;
}
}
</script>
The saveInfo() method is made in a button:
<input type="submit" value="Save" onclick="saveInfo()" style="color: black">
So there are 2 forms, where you fill up your email and name. By clicking "Save" -button, the DIV will disappear (this works) and another DIV will appear within text like this: Name = (name) | Email = (email).
I am having problems to call the saveInfo()'s returnEmail() for the corresponding line (where there is 'Name = ').
I try to write them like this:
<p>Email:
<script>
var pEmail = saveInfo().returnEmail();
document.write(pEmail);
</script> <br>
</p>
I know that the script above is incorrect, this is not the only way I have tried to return it.
It looks like you're trying to return those functions to use later. Try doing this instead. This function now returns an object with two functions.
function saveInfo() {
return {
returnEmail: function() {
var _e = document.getElementById("email").value;
return _e;
},
returnName: function() {
var _n = document.getElementById("name").value;
return _n;
}
}
}
Previously, your saveInfo function wasn't returning anything, so
saveInfo().returnEmail();
would evaluate to
undefined.returnEmail();
and you'd get an error
You need to return the exposed functions from the function saveInfo. At this time, your code only declares the function, but doesn't return anything. So, saveInfo returns undefined. Below approach is an implementation of the Revealing module pattern to reveal the public members outside your function.
function saveInfo() {
var returnEmail = function () {
var _e = document.getElementById("email").value;
return _e;
}
var returnName= function () {
var _n = document.getElementById("name").value;
return _n;
}
return {
returnEmail :returnEmail,
returnName :returnName
}
}
If your set on calling it like saveInfo().returnEmail(); then you can do the following. saveInfo returns an object containing the returnEmail method.
<script>
function saveInfo() {
// Do any desired logic
return {
returnEmail: function() {
var _e = document.getElementById("email").value;
return _e;
},
returnName: function() {
var _n = document.getElementById("name").value;
return _n;
}
}
}
</script>

Returning a value from a from a protractor promise inside a function

I’m trying to get text from a page and then use that text further down in the spec to assert on another element.
I’ve pasted a very simple spec you can run that shows you can’t return a value from a function if the function’s return statement is inside a protractor promise return txt; (line 24)…
describe('My Test', function () {
var tempVariable;
it('should go get some text from the page', function () {
browser.get('https://angularjs.org/');
tempVariable = getTextFromElement(); //it appears javascript immediately sets this variable before waiting for protractor to return the value
});
it('should do some random other stuff', function () {
element.all(by.cssContainingText('a', 'Learn')).get(0).click();
element.all(by.cssContainingText('a', 'Case Studies')).get(0).click();
element.all(by.cssContainingText('a', ' Home')).get(0).click();
});
it('should be able to use the text from the first page in this test', function () {
console.log('\ntempVariable: ' + tempVariable); //this is undefined!
expect(typeof tempVariable).not.toBe('undefined', 'failed: tempVariable was undefined!');
});
});
function getTextFromElement() {
$('a.learn-link').getText().then(function (txt) {
console.log('\nInitial text: ' + txt);
return txt; //how do we return this so it's available to other 'it' blocks?
});
}
Updated snippet of code following #alecxe answer and my comment.
I am attempting to contruct an object from various text on a page and return it to assert on in a later page...
function getRandomProductFromList() {
var Product = function (line, name, subname, units) {
this.line = line;
this.name = name;
this.subname = subname;
this.units = units;
};
var myProduct = new Product();
myProduct.line = 'Ford';
myProduct.units = 235;
//select a random product on the page and add it to 'myProduct'
var allProducts = element.all('div.product');
allProducts.count().then(function (count) {
var randomIndex = Math.floor(Math.random() * count);
var productName = allProducts.get(randomIndex);
productName.getText().then(function (prodName) {
myProduct.name = prodName;
productName.click();
});
});
//If a sub-product can be chosen, select it and add it to 'myProduct'
var subproduct = $('div.subproduct');
subproduct.isDisplayed().then(function (subProductExists) {
if (subProductExists) {
subproduct.getText().then(function (subProductName) {
myProduct.subname = subProductName;
});
subproduct.click();
}
}, function (err) {});
return myProduct;
}
First of all, you are not returning anything from the function:
function getTextFromElement() {
return $('a.learn-link').getText();
}
Now, this function would return you a promise which you need to resolve before using:
it('should be able to use the text from the first page in this test', function () {
tempVariable.then(function (tempVariableValue) {
console.log('\ntempVariable: ' + tempVariableValue);
expect(typeof tempVariableValue).not.toBe('undefined', 'failed: tempVariable was undefined!');
});
});
Plus, to determine whether a variable is defined or not, I would use toBeDefined() from jasmine-matchers:
expect(tempVariableValue).toBeDefined();
None of the above worked for me. This is working for me:
var item = element.all(by.xpath("some xpath here"));
this.methodToGetTheText = function () {
return Promise.resolve(item.getText().then(function (text) {
return text;
}));
}
Thanks to #alecxe for starting me off on the right foot.
I found a solution I am now using quite a bit after reading this.
By passing an object by reference, you can add properties on the fly and use them later in your spec.
Example:
describe('My Test', function () {
var tempObject = {};
it('should go get some text from the page', function () {
browser.get('https://angularjs.org/');
getTextFromElement(tempObject); //pass an object by reference to populate with page text
});
it('should do some random other stuff', function () {
$('div.someDiv').click();
});
it('should be able to use the text from the first page in this test', function () {
console.log(tempObject.textFromFirstPage); //works!
});
});
function getTextFromElement(tempObject) {
$('a.some-link').getText().then(function (txt) {
tempObject.textFromFirstPage = txt;
});
}
Are you calling methodToGetTheText().then( from your spec? The value inside the .then() function should contain your actual page text

Understanding how javascript works when a parent function returns an inner function

I have an inner_function inside a parent_function.
I think I understand how this works: http://jsfiddle.net/93pp5/
var text = 'Look at me';
function parent_function() {
function inner_function() {
var scream = '!!!';
alert(text);
}
inner_function();
};
parent_function();
However, I'm trying to figure out why my javascript below does not work. Can parent_function() not return inner_function()? My expectation was that calling parent_function() at the bottom would bring up an alert, but it does not: http://jsfiddle.net/93pp5/1/
var text = 'Look at me';
function parent_function() {
return function inner_function() {
var scream = '!!!';
alert(text);
}
};
parent_function();
Thats because parent_function returns a function which still needs to be called (executed).
var runAlert = parent_function();
// runAlert now holds the returned function but it still needs to be called to get the alert
runAlert(); // will alert

Categories

Resources