How to apply a method to an entire object literal? - javascript

How do you apply a method to all properties of an object literal?
For Example:
var ObjL = {
x: $("someSelector > .x"),
y: $("someSelector > .y"),
otherx: $("someOtherSelector > .x"),
othery: $("someOtherSelector > .y"),
...
...
...
}
// <---something like ObjL.css("background-color","red") would go here
Would you just use ObjL.someMethod()?
Could you do this with an array?

If I understand you correctly, you want to apply a method aMethod to an element? The best solution IMHO is a foreach loop:
$.each($obj, function(prop, value) {
//call a method here, being the same on value or this.
value.css(blablabla, blablabla);
});
(deliberately i did not use the for loop since 1. u're using jquery and it's shorter, and 2. it has many problems regarding the owned or inherited-by-proto properties).
EDIT: yes, you can use a $.each loop as well for arrays. an alternative is using a regular for-counter loop (for(initial;condition;increment){ code }), since using for(in) loops in arrays lead to unexpected results.

This should do the trick
$.each(ObjL, function() {
this.css("background-color","red");
})

You could iterate over the object:
for (var key in ObjL) {
if (ObjL.hasOwnProperty(key)) {
ObjL[key].css( /* do your thang */ );
}
}

Related

forEach not changing values of array

availableButtons.forEach(function(part, index) {
console.log(this[index].title)
// this[index].title = intl.formatMessage(this[index].title);
}, availableButtons)
The code above prints the console as follows:
{id: "abc.btn.xyz", defaultMessage: "someMessage"}
This confirms that each object has an id but when I try to execute the commented code it throws an error saying [#formatjs/intl] An id must be provided to format a message.
I used the same array but only a single object separately as follows intl.formatMessage(availableButtons[0].title); this gave me the required result I am just not able to figure out. I tried various ways of passing values in forEach, what am I missing?
forEach does not actually mutate arrays. it's just a shorthand loop called on the array. It's hard to suggest a solution because your intent is not clear.
availableButtons = availableButtons.map(button => {
//do your mutations here
}
might be a start
I think Array#map works better for in this vade
availableButtons.map(part => {
return {
...part,
title: intl.formatMessage(part.title)
};
});
Access the array (availableButtons) directly and update (mutate) with forEach.
availableButtons.forEach(function (part, index) {
console.log("before: ", availableButtons[index].title);
availableButtons[index].title = intl.formatMessage(this[index].title);
console.log("after: ", availableButtons[index].title);
});

Why is it returning undefined?

I want to store as the following method, and get the constant value, by querying using key to find value or by value to find the key
function my_reference() {
return {
30:'',
31:'ERR591',
32:'ERR761',
33:'ERR671',
34:'ERR551',
};
}
console.log( my_reference[31],
my_reference.31,
my_reference().31,
my_reference()[31]
);
my_reference[31],
Trying to read a property (which doesn't exist) of a function. The property is on the object that is the return value of calling the function.
my_reference.31,
Trying to use a number as an identifier. This isn't allowed.
my_reference().31,
Trying to use a number as an identifier. This isn't allowed.
my_reference()[31]
This works
You need to execute the function with my_reference() and after that access the property you want to.. but the keys in javascript objects are always strings:
console.log(my_reference()['31']);
You don't need to use a function to store the references:
var reference = {
30:'',
31:'ERR591',
32:'ERR761',
33:'ERR671',
34:''
};
console.log(reference[31]);
You have to call function if you want it to return result, function called by :
my_reference()
So the both first lines will not work because my_reference will return the function it self and not call it :
my_reference[31]
my_reference.31
The third also will not work console.log(my_reference().31); because attribute can't be numeric.
Hope this helps.
Here is the fixed code
function my_reference() {
return {
_30:'',
_31:'ERR591',
_32:'ERR761',
_33:'ERR671',
_34:'ERR551'
};
}
var f = my_reference();
console.log(f["_31"]);
console.log(f._31);
console.log(my_reference()._31);
console.log(my_reference()["_31"]);
Variables can't be named with just numbers
The first two should be the returned object

How to determine if $(this) is in array on click event

I have a set of id values in 4 arrays. Each array will be assigned a text value for an h1 and a p that I haven't put in yet. Right now I'm just trying to get it to alert if one of the images in array graphicDesign is clicked. I tried using $.inArray
DEMO
var graphicDesign = [$('#design'), $('#DD'), $('#SElogo')];
var webDesign = [$('#bootstrap'), $('#farm'), $('#pong'), $('#SE'), $('#dung')];
var programming = [$('#SE'), $('#dung'), $('#sacar')];
var other = [$('#firm')];
function categories() {
if ($.inArray(this, graphicDesign) > -1) {
alert('hello');
}
}
You should not store DOM objects in an array and try to match them with $.inArray.
Using ids or another attribute would be a better solution.
For example :
https://jsfiddle.net/1f9xd3t0/
var graphicDesign = ['design', 'DD', 'SElogo'];
function categories(id) {
if ($.inArray(id, graphicDesign) > -1) {
alert('hello');
}
}
categories('design');
You need to pass the event object to categories().
$('.portPic').click(function(e) {
// ...
categories(e);
});
function categories(e) {
console.log(e.target);
if ($.inArray(e.target, graphicDesign) > -1) {
alert('hello');
}
}
UPDATE
And maybe use id's rather than jQuery objects in your arrays.
var graphicDesign = ['design', 'DD', 'SElogo'];
Then use e.target.id in categories().
You can use typeof , here is an example.
// Objects
typeof {a:1} === 'object';
// use Array.isArray or Object.prototype.toString.call
// to differentiate regular objects from arrays
typeof [1, 2, 4] === 'object';
Array.indexOf() is a native function that does the same thing.
graphicDesign.indexOf(this) > -1 would be the equivalent of what you wrote.
In your usage, this is going to refer to the global object, unless you elsewhere assign this function to an object and call it as a method... But then you're trying to tell if the object you're calling it on is inside the graphicDesign array?
Here's an example of a usage that would fire the alert:
var graphicDesign = [ {} ]
graphicDesign[0].categories = function() {
if (graphicDesign.indexOf(this) > -1) {
alert('the object this method was called on is inside the graphicDesign array')
}
}
graphicDesign[0].categories()
It's unclear exactly what you're trying to accomplish, however (you mention a click detection, but there's no click handler here, etc.)... I hope this helps?
This block of $.inArray is working, but you put them in wrong place, it always returned -1, so you cannot get the alert('hello'). Please fix the overall logic.
if ($.inArray(this, graphicDesign) > -1) {
alert('hello'); }

can't get nested forEach to work in Javascript

So I guess the title is selfexplanatory. I have some code with nested forEach loops inside it. The loops are iterating over an array of chapter objects. Each object can have multiple child nodes and they again can have multiple child nodes, and so on.
I want to end up with one array which contains nested arrays with the child nodes.
So far my code looks like this:
exports.chapter = function(req, res) {
var chapters = [],
result = [];
chapters = exports.index(req, res);
chapters.forEach(function(chapter) {
if(chapter.orphan){
result.add({
'chapter': chapter,
'children': getChildren(chapter.children)
});
}
});
function getChildren(siblings) {
var children = [];
chapters.forEach(function(chapter) {
if($.inArray(chapter, siblings)){
children.add({
'chapter': chapter,
'children': getChildren(chapter.children)
});
}
});
return children;
};
};
I don't get any errors except for my page not loading. It doesn't write anything in my console. I think it's a problem in the setup but I'm unable to find out where at the moment. Really hope you guys can help.
Most likely problem is here:
if($.inArray(chapter, siblings)){
$.inArray is a horribly misnamed method: It returns an index, or -1 if not found, not a flag as the name implies. -1 is, of course, truthy; and 0 (a valid index), is falsey, so your if probably wants to be
if($.inArray(chapter, siblings) != -1){
// We found it...
}
or possibly
if($.inArray(chapter, siblings) == -1){
// We didn't find it
}
It's a bit strange.. I don't understand why you're using 'add' instead of 'push' method. If I try to "add" an object to an array I get an usual error. Don't you?

Find data() key-value pairs for every element

What is the best way to view all jQuery data key-value pairs across every element (in jQuery 2.x)?
A selection-oriented approach ( e.g. $('*').data() ) obviously does not work, because the return value is tied to a single element.
I know that I can iterate over every element, checking each for data:
var allData = [];
$('html *').each(function() {
if($.hasData(this)) {
allData.push({ el: this, data: $(this).data() })
}
})
JSFiddle
This does produce the expected output, but iterating over each possible data key feels like a backwards approach to this problem.
Is there some way to find all element data directly?
N.B. I'm interested for debugging, not production code.
You could select every element within the body with $("body *") and apply jQuery's .filter() to it. Working example:
var $elementsContainingData $("body *").filter(function() {
if($.hasData(this)) return this;
});
console.log($elementsContainingData);
Edit
As #spokey mentioned before, there's an internal variable named "cache" within the jQuery object: $.cache.
This variable consists of a bunch of objects which contain keys like "data" or "events":
5: Object
data: Object
events: Object
handle: function (a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)}
__proto__: Object
You can iterate through that object and filter for the data:
var filteredCache = $.each($.cache,function() {
if(typeof this["data"] === "object") return this;
});
Here's an working example plus a function to merge that stuff into a single and more handy object consisting only of dataKey => dataValue pairings: Fiddle
Edit
As mentioned in comments this solution does not work in jQuery version 2.x since $.cache is deprecated.
My last suggestion is creating a hook for jQuerys data function in order to extend an own object$.dataCache = {}; each time data() is called.
Extending, replacing or adding jQuerys functions is done by accessing $.fn.functionName:
$.fn.data = function(fn,hook) {
return function() {
hook.apply(this,arguments);
return fn.apply(this,arguments);
}
}($.fn.data,function(key,value) {
var objReturn = {};
objReturn[key] = value;
$.extend($.dataCache,objReturn);
});
This also works great in jQuery version 2: Fiddle

Categories