Add existing element to Object - javascript

I have next object:
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
Also I have function that returns elements (it's value depends from different conditions):
function getNewElement(condition1, ..., conditionN) {
...
return { "my btn": function() { alert(kkk); } }
}
How I can add to myArray value that returns me getNewElement function?

myArray["fn"] = getNewElement;

Do you mean
myArray["newElement"] = getNewElement();
or
myArray["my btn"] = getNewElement()["my btn"];
?

Another way to create new Objects
var myObj = {
firstName : "Gareth"
lastName : "Simpson"
};
function getNewElement(condition1, ..., conditionN) {
return { "my btn": function() { alert(kkk); } }
}
myObj.getNewElement;
//to call the function
myObj.getNewElement();

Related

Why won't a boolean object property update?

I have an array of objects. Each object has a method that should update a boolean property in the same object called 'found'.
When I call the function, the property does not update. I am not sure why.
I thought that the 'found' property would be accessible but it isn't??
I have created a minimal version of the problem here:
https://codepen.io/sspboyd/pen/XWYKMrv?editors=0011
const gen_s = function () { // generate and return the object
let found = false;
const change_found = function () {
found = true;
};
const update = function () {
change_found();
};
return {
change_found,
found,
update
};
};
const s_arr = []; // initialize an array
s_arr.push(gen_s()); // add a new s object to the array
console.log(s_arr[0].found); // returns 'false'
s_arr.forEach((s) => {
s.update();
});
console.log(s_arr[0].found);
When your change_found function changes the value of found, it's changing the value pointed to by your let found variable, but the object returned by your gen_s function still points to the old value.
You can fix your code using the 'holder' pattern, like this:
const gen_s = function () { // generate and return the object
let foundHolder = {value: false};
const change_found = function () {
foundHolder.value = true;
};
const update = function () {
change_found();
};
return {
change_found,
foundHolder,
update
};
};
const s_arr = []; // initialize an array
s_arr.push(gen_s()); // add a new s object to the array
console.log(s_arr[0].foundHolder.value); // returns 'false'
s_arr.forEach((s) => {
s.update();
});
console.log(s_arr[0].foundHolder.value);
Or even better, use a class:
class S {
constructor() { this.found = false; }
change_found() { this.found = true; }
update() { this.change_found(); }
}
const s_arr = [];
s_arr.push(new S());
console.log(s_arr[0].found);
s_arr.forEach(s => s.update());
console.log(s_arr[0].found);

How to make local varible global javascript

I have this class like so :
https://jsfiddle.net/0sh7fLtp/
When I create a new object of this class, my local variable can't be seen even when I assign to window in the class:
function Hilitor() {
var excat;
this.setMatchType = function(type) {
if (type == "exact"){
window.excat = true;
}
};
this.setRegex = function(input) {
alert(excat);
};
this.apply = function(input) {
this.setRegex();
};
}
and this is how i call it :
var myHilitor = new Hilitor();
myHilitor.apply();
myHilitor.setMatchType("exact");
Not sure I completely understand your question but you are trying to compare a variable "excat" to string "excat"... See this fiddle to how you can make your var a string and then get desired output..
https://jsfiddle.net/shemdani/0sh7fLtp/5/
var myHilitor = new Hilitor();
myHilitor.setMatchType("excat");
myHilitor.apply();
function Hilitor()
{
var excat;
this.setMatchType = function(type)
{
if(type == "excat"){window.excat = true;}
};
this.setRegex = function(input)
{
alert(window.excat);
};
this.apply = function(input)
{
this.setRegex();
};
}
Two main problems
1) Your var exact inside the function is not a global variable and so not accessible on the window object. (But that's a good thing).
Your code will work if you remove window.exact for just exact
this.setMatchType = function(type)
{
if(type == "exact"){excat = true;}
};
2) You are also calling apply before you call setMatchType. Switching them like this works:
var myHilitor = new Hilitor();
myHilitor.setMatchType("excat");
myHilitor.apply();
Working example

jQuery - $.extend not returning expected functions

I'm using gmail.js for some project. In the library, there is a function like this :
api.dom.compose = function(element) {
// stuff
}
api.dom.email = function(element) {
this.id = element;
var message_class_id = 'm' + this.id;
this.id_element = $('div.ii.gt div.a3s.aXjCH.' + message_class_id);
element = this.id_element.closest('div.adn');
this.$el = element;
return this;
};
$.extend(api.dom.email.prototype, {
body: function(body) {
var el = this.dom('body');
if (body) {
el.html(body);
}
return el.html();
},
from: function(email, name) {
var el = this.dom('from');
if (email) {
el.attr('email',email);
}
if (name) {
el.attr('name',name);
el.html(name);
}
return {
email: el.attr('email'),
name: el.attr('name'),
el: el
};
},
// more extended functions
});
// more functions on the api.dom object
return api;
In my code I'm using it like so :
var email = provider.dom.email(mId);
console.log(email);
The console.log is really surprising. I was expecting to see the functions from the $.extend section. In that place, the functions showing are those registered on the api.dom object ! email() itself, compose, and more.
I don't get at all why this is happening. Thanks ahead for any help.
It was the prototype that has been extended. The functions are available when creating an instance with new. So do a console.log(api.dom.email.prototype); or create a new instance with new.
var email = new provider.dom.email(mId);
console.log(email);

How to chain method to returned string value

Below there's a function that returns the string depending on a current language, for example if the language is "it"
var currLang = "it";
var language = (function () {
/*this.uppercase = function(){
// the following is more like a pseudo since makes no sense:
return this.toUpperCase(); // I mean, it's wrong... I know :(
};*/
return {
it : {
hi : "ciao"
},
es : {
hi : "ola"
}
}[ currLang ];
})();
console.log( language.hi ); // ciao
console.log( language.hi.toUpperCase() ); // CIAO
Above I'm happy to use it like it is, chaining the JS's vanilla String prototype toUpperCase, but I was just wondering:
how to chain a method we created... like .toUpperCase or a custom one like .toFirstUppercase() ? For example:
language.hi.toFirstUppercase()
but keeping our toFirstUppercase inside the language function?
My problem is that language.hi already returns a string, I know that .toUpperCase() operates on the object "String".toUpperCase() but how to make a custom method inside my app that will help to achieve the same?
Please, if the question is not clear I'd like to improve it so let me know! Thx for any suggestion
Use prototypes and add a toFirstUpperCase method to the String.prototype object. This will instantiate an instance of the toFirstUpperCase closure function for every instance of String:
var currLang = "it";
var language = (function () {
/*this.uppercase = function(){
// the following is more like a pseudo since makes no sense:
return this.toUpperCase(); // I mean, it's wrong... I know :(
};*/
return {
it : {
hi : "ciao"
},
es : {
hi : "ola"
}
}[ currLang ];
})();
String.prototype.toFirstUpperCase = function()
{
return this[0].toUpperCase() + this.slice(1, this.length);
}
console.log( language.hi ); // ciao
console.log( language.hi.toUpperCase() ); // CIAO
console.log( language.hi.toFirstUpperCase() ); // Ciao
JavaScript doesn't have classes and other things like that, but I would do something like the following:
Creating an object
var Word = function (word) {
var _value = word; //Private variable, modify _value as needed
Object.defineProperties(this, {
'value': {
enumerable : true,
get : function (a) { return _value; },
set : function (a) { _value = a; }
},
//Functions
'uppercase': {
get : function () { return _value.toUpperCase() }
}
});
};
Then:
//...
'hi': new Word('ciao')
//...
Then:
language.it.hi.value; // ciao
language.it.hi.uppercase; // CIAO
JavaScript variables can be made using their constructor new Array(), new String(), etc. We can use this and then just add a function.
Using string as an object
Also, you can just add something to the string using the constructor:
var Word = function (word) {
var _word = new String(word); // new String() is essential
_word.toFirstUppercase = function () {
return this.toUpperCase();
};
return _word;
};
Then:
//...
'hi': new Word('ciao')
//...
alert(language.it.hi); //'ciao'
alert(language.it.hi.toFirstUppercase); //'CIAO'
var Word = function (word) {
var _word = new String(word); // new String() is essential
_word.toFirstUppercase = function () {
return this.toUpperCase();
};
return _word;
};
var currLang = "it";
var language = (function () {
/*this.uppercase = function(){
// the following is more like a pseudo since makes no sense:
return this.toUpperCase(); // I mean, it's wrong... I know :(
};*/
return {
it : {
hi : new Word("ciao")
},
es : {
hi : new Word("ola")
}
}[ currLang ];
})();
console.log( language.hi ); // ciao
console.log( language.hi.toFirstUppercase() ); // CIAO
var currLang = "it";
var language = (function () {
//You could also add it to the String.prototype so you could chain it with other methods:
String.prototype.toFirstUppercase=function(){
s = this;
return s.length > 0 ? s.charAt(0).toUpperCase() + s.slice(1) : s;
};
return {
it : {
hi : "ciao"
},
es : {
hi : "ola"
}
}[ currLang ];
})();
//and use it like this:
console.log(language.hi); //ciao
console.log(language.hi.toFirstUppercase()); //Ciao
Another solution:
var currLang = "it";
var language = (function () {
String.prototype.toFirstUpperCase = function(){
return this[0].toUpperCase() + this.slice(1, this.length);
};
var hi;
switch(currLang){
case "it":
hi = "ciao";
break;
case "es":
hi = "ola";
break;
default:
hi = "hello";
}
//simple
//return hi;
//object
return {
hi : hi
};
})();
//use
console.log(language.hi);
console.log(language.hi.toFirstUpperCase());

Associate a string with a function name

I have a text input that I want to enable users to call functions from.
Essentially I want to tie strings to functions so that when a user types a certain 'command' prefaced with a backslash the corresponding function is called.
Right now for example's sake you can type /name, followed by a value and it will set name as a property of the user object with the value the user gives.
So how would I do this with 20 or so 'commands'?
http://jsfiddle.net/k7sHT/5/
jQuery:
$('#textCommand').on('keypress', function(e) {
if(e.keyCode==13) {
sendConsole();
}
});
var user = {};
var sendConsole = function() {
value = $('#textCommand').val();
if (value.substring(0,5) === "/name") {
user.name = value.substring(6,20);
alert(user.name);
} else {
$('body').append("<span>unknown command: "+value+"</span><br />")
$('#textCommand').val("");
}
}
HTML:
<input id="textCommand" type="text"><br/>
Store your functions in an object, so you can retrieve and call them by key:
// Store all functions here
var commands = {
name : function() {
console.log("Hello");
}
}
var sendConsole = function() {
value = $('#textCommand').val();
// Strip initial slash
if(value.substring(0,1) === '/') {
value = value.substring(1);
// If the function exists, invoke it
if(value in commands) {
commands[value](value);
}
}
}
http://jsfiddle.net/NJjNB/
Try something like this:
var userFunctions = {
run: function(input)
{
var parts = input.split(/\s+/);
var func = parts[0].substr(1);
var args = parts.slice(1);
this[func].call(this, args);
},
test: function(args)
{
alert(args.join(" "));
}
};
userFunctions.run("/test hello there"); // Alerts "hello there".
You can do:
if(window["functionName"])
{
window["functionName"](params);
}

Categories