Is there a map() function in ExtJS? - javascript

ExtJS has Ext.each() function, but is there a map() also hidden somewhere?
I have tried hard, but haven't found anything that could fill this role. It seems to be something simple and trivial, that a JS library so large as Ext clearly must have.
Or when Ext really doesn't include it, what would be the best way to add it to Ext. Sure, I could just write:
Ext.map = function(arr, f) { ... };
But is this really the correct way to do this?

As of at least Ext4, Ext.Array.map is included.
http://docs.sencha.com/extjs/5.0.1/#!/api/Ext.Array-method-map

Since map is more of a utility than anything, I don't see why there would be any special way of plugging it into the Ext namespace; the way you propose would work well enough, though you might want to do it thusly:
if(Ext && typeof(Ext.map) == "undefined") { // only if Ext exists & map isn't already defined
Ext.map = function(arr, f) { ... };
}
Seems like that would be fine...but then, I don't use ExtJS, so I don't know. I did take a gander at their docs and it doesn't seem like there is anything special to do in this case.

It appears, that my colleges here are using ext-basex, which extends Array.prototype with map() and other methods.
So I can just write:
[1, 2, 3].map( function(){ ... } );
Problem solved.

What about using one of the hybrid libraries like Ext+Prototype or Ext+Jquery. I've been using Extjs+Prototypejs for a while now and it helped me a lot to work into the Extjs code with having the more familiar prototypejs along for the ride as well.
http://extjs.com/products/extjs/build/ will build a custom tar/zip file of all the files you need to run extjs and (prototypejs|jquery|yahooUI).

ExtJS doesn't replace Javascript language itself. Array functions aren't in the focus of ExtJS core. However there is a special Ext.Array object type. You can extend it on your own.
EDIT: Not Ext.Array, but just extended Array object.

Related

js array search function for ie8

I've written a js lib that needs to work in ie8 and I've been asked not to use jQuery as part of the implementation. Part of the js lib requires searching an array for a matching value. Modern browsers support the array indexOf() function which will accomplish this. However, since my js lib needs to support ie8 I won't be able to use this function. Initially I wrote the following custom function:
function inArray(anArray, aValue)
{
for (var i = 0; i < anArray.length; i++)
if (anArray[i] === aValue) return true;
//value was not in array
return false;
}
However, this morning it occured to me that it would be better to write this using prototypal inheritance. What would be a good way to rewrite this using prototypal inheritance? Also, is there a way I can go into the direct source code used for the ES standard, copy the indexOf() function and paste it into my custom js lib? Not sure if this is possible or not but it seems like a good way to port snippets without reinventing the wheel.
You're probably best off with a utility function you pass the array into, such as the inArray in your question.
You could add a shim for Array#indexOf or includes or similar to Array.prototype, but if you did, it would become enumerable and show up in for-in loops. People shouldn't use for-in to loop through arrays, but sadly, they sometimes do. If they do in your codebase or any library your codebase includes, that will be a problem.
Unfortunately, you can't make it non-enumerable because IE8 doesn't support Object.defineProperty (except on HTML elements, oddly).
As a general rule, having your own namespace and using a function like you've described is probably better for a library, something like this:
MyLib.inArray = function(array, value) {
// implementation here
};
You could modify the prototype of Array with the ES6 function .includes() like so:
Array.prototype.includes = Array.prototype.includes || function(needle) {
// implementation here
};
and then you can use it like so:
[1, 2, 3].includes(3); // true
(Note that if it already exists, we don't override it)
However, this is generally bad practice to do in a library, because you're modifying a reference to a build-in function that other scripts on the page may rely on! Additionally, properties added this way will show up when iterating the array with for..in, which is extremely undesirable.

How does extending work in LeafletJS and why do I need an intermediary attribution for it to work correctly?

First of all, this might not be a LeafletJS question, but a mere JS one, but I haven't come across it until Leaflet.
I've been experimenting with Leaflet lately and at some point wanted to pass to a function an extended version of a Control object (for those who also work with Java or similar language, I was trying to do something similar with instantiating an anonymous class).
So:
Given the class L.Control (which I wanted to extend with the method x), I tried:
func(new L.Control.extend({x: function() {}})());
which fails miserably, because the parameter of the function func is undefined.
However:
var v = L.Control.extend({x: function() { }});
func(new v());
works perfectly, as new v() returns, as expected, a L.Control object with an extra x function.
Bottom line: what is the difference between the 2 snippets of code and how can I make it work with a one-liner (if possible)?
Thanks!
After some experiments, I figured it out by myself.
The problems is due to the order of operations and the solution was to add a set of brackets, the one-liner becoming:
func(new (L.Control.extend({x: function() {}}))());

Is There a Way to Implement EventTarget with Plain JS?

I'm trying (perhaps in vain) to come up with a way to use the publish-subscribe pattern while a) using no libraries and b) minimizing boilerplate code in modules that use it. So far the best I've come up with is this:
var handle = document.createElement();
var unsubscribe = AwesomeModule.subscribe(handle);
handle.addEventListener('awesome', function() {
console.log('awesome');
});
This will work pretty well, except that people using AwesomeModule might be confused by having to provide a random DOM element that isn't used as an element.
I tried the following and it doesn't work too well:
var handle = Object.create(EventTarget);
var unsubscribe = AwesomeModule.subscribe(handle);
handle.addEventListener('awesome', function(){
console.log('awesome')
});
I get TypeError: Object [object Object] has no method 'addEventListener'. Interestingly enough, it doesn't seem to look in the prototype chain even though handle has EventTarget as its prototype.
Why doesn't this work? Is there a way implement EventTarget with pure JS? Can it be done in a single line of code that won't horrify users of AwesomeModule?
EDIT: I don't know why it didn't occur to me last night, but I suppose EventTarget being an interface means that it doesn't have implemented code. What's confusing is that in the Chrome debugger console Object.create(EventTarget) makes an object that appears to have addEventListener in is prototype chain. Maybe its lying. Can anyone explain this behavior? Can anyone explain why W3 chose not to make EventTarget a concrete "class"?
It looks like the answer to my original question is "yes." Since JavaScript doesn't have an inheritance model like Java which does compile-time checks for legal implementation, I suppose any Object can implement an interface merely by having methods with the same name. However, doing this would constitute making a library since the addEventListener code isn't implemented in EventTarget (I had previously assumed it was). Since there seems to be no cross-browser way to get a vanilla EventTarget, I will probably use window.addEventListener in conjunction with custom events.
The source is located here: https://code.google.com/p/chromium/codesearch#chromium/src/third_party/trace-viewer/src/base/event_target.js&sq=package:chromium&type=cs&l=18
If you can't modify it, you can always replicate it.
Here's a simple set of routines that works well.
with a small polyfill for IE9 and 10, support is decent.
you can incorporate these functions into your project as needed, i don't think it constitutes a library, or i wouldn't post this.
var on = addEventListener.bind(window),
off = removeEventListener.bind(window),
emit = function(name, val) {
dispatchEvent(new CustomEvent(name, {
detail: val
}));
};
// demo:
on("test", function(e){ alert(e.detail);});
emit("test", "Number is " + Math.random());
i don't think it can get much simpler (~180 chars) without sacrificing speed or library compatibility.

When should I use data type classes in JavaScript

I come from a C# background. I've been working a lot with JavaScript lately. On a new app, I have a mysql/php back end. I'm going to be passing a lot of "types" back and forth.
So in my data base, I have several tables like
table1
id, fieldx,fieldy,fieldz
table2
id, fielda,fieldb,fielc
In c# I would definitely write classes for all those in the code. Which led me to implement things like so (in my JavaScript app):
function table1(id, x,y,z){
this.id=id;
this.x=x;
this.y=y;
this.z=z;
}
After about 6 tables worth of that, it suddenly occurred to me that maybe there was no point at all in making these classes.
So my question is, in a JavaScript app, do I use "classes" for data types? or should I just "document" which fields/types are expected and so in the code instead of
a.push(new table1(5,1,2,3));
I would just have
a.push({id:5,x:1,y:2,z:3});
This may seem like a preferences question but it's a fundamental language question that I have as I try to understand how to model my app's data in JavaScript. Is there any advantage of the classes (with only data fields) or is it just a mistake. Thanks.
It depends,
Note: Most of the programmers coming from a strong OO language will have trouble like you in regard to JavaScript's functional behavior (you are not alone).
If you want to create something closer to C# I would do the following:
function Table1(id, x, y, z) {
this.id=id;
this.x=x;
this.y=y;
this.z=z;
}
Table1.prototype.mySpecialTable1Method= function()
{
console.log(this.id);
};
Implementation:
var t = new Table1(1, 2, 3, 4);
t.mySpecialTable1Method();// outputs: 1
If you need to have methods that interact with the (soon to be) objects then I would definitely go with the code above. In addition it will make it clear when working with the objects that are related to a specific 'type' (naming the data).
But if your objects do not require any special "treatment" then I don't see any problem to use normal js object literals and pass them along (probably good for small projects).
Something along the lines:
var table1 = {};
table1.id = 1;
table1.x = 2;
table1.y = 3;
table1.z = 4;
console.log(table1.id); //outputs: 1
Extra reference:
http://www.youtube.com/watch?v=PMfcsYzj-9M
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
Update:
For the sake of readability and scalability and the point that you are coming from C# you may want to stick to the "class" implementation just because it will define the correlation between the raw data and the objects you are working with.
There is a good chance that you are going to work with some data that will probably be messy and unorganized.
MVC may be the solution for you. It tries to bring some order to the chaos that you are expecting. I recommend to check out some of them like: AngularJS or Ember.
Another solution may be reactive js - but mostly if you are going to interact with the DOM according to your data (ReactJS, and Facebook's React as some good ones).
As a note for security, I would like to add that mapping the data closely to the db isn't a best practice but its your call.
Javascript is a funny language, and there are plenty of ways to do things. An Object is an Object in Javascript with or without a name. {} is just a short-hand way to create one.
If you are going for readability, then your initial example would be the way to go.
If you just want to get the block of data into an array, then your second example is appropriate. Personally, I would use your later example if it is just data.
If you are using functions and what not as well as data storage, and plan on reusing it several times in your code, then yes, define your object and call it appropriately.
JavaScript has no classes, it is a functional language and a function is a first class citizen in js meaning that a function is an object.
From your example I can see that your intention for classes is simply to pass data and using json is perfect for this.

How to create a catch all function on a jQuery object?

I was previously using the jQuery autosave plugin but have recently removed it. Some code is still trying to use this function, so how can I temporarily extend the jQuery object so there is an empty function to prevent errors until I can get through all of the code that is trying to use the function?
The plugin is called in this way:
jQuery().autosave.restore();
jQuery().autosave.save();
I think those are the only two functions that exist, so it would be OK to create two empty functions, but is there a way to create a catch-all function on this type of object?
Note
This is a temporary solution until I can go through a lot of code. I do believe the question is a valid coding question even if you think this workaround is not ideal (it isn't).
There is a way to do this. You can create a dummy plugin (check out jQuery's documentation for creating plugins):
(function( $ ){
$.fn.autosave = {
restore: function() {};
save: function() {};
};
})( jQuery );
I would highly recommend against doing this, however. Instead, you should look at those errors and fix them, i.e., stop your code from using them. Otherwise you're simply hiding the problem.
Nope. Standard JavaScript does not support "catch-all" methods.

Categories