I've been working a personal Vue project that includes a simple Google map.
While implementing the Maps JS API, I annoyingly kept encountering the ESLint error 'map' is assigned a value but never used. I understand why I'm getting this error—The Map() constructor returns a value that I don't need to do anything with:
const map = new google.maps.Map(el, options)
So I eventually just implemented the solution described in this Stack Overflow answer to bypass the lint rule.
If you're using a poorly designed library where the class constructor has side effects (which it isn't supposed to), and you don't need to do anything with the returned value from the class, I would disable that specific eslint rule for those lines.
However, my question is, why is Google's Map() constructor designed in this way? I have a hard time believing this library would be "poorly designed" but can't see a reason for this implementation.
It not side effect. It's returning instance of it. So you can call further methods on it
Related
I recently got to know about ES6 proxies but I don't see a good reason to use it. I mean, everything that one could do with Proxy can be done without it, except if I'm missing something.
For example, most folks talk about validation when it comes to proxy but one could apply some JS goodness to validate and everyone is fine. I would appreciate if someone could open my eyes to some major use cases of Proxies. Thanks!
I mean, every thing that one could do with Proxy can be done without it...
That isn't remotely true.
Consider the common need to catch access to properties that don't exist:
const o = {foo: "bar"};
console.log(o.blarg);
It's common to want to handle that in a way other than the default, which is to log undefined. Proxy lets us do that, via the get trap. Example:
const o = {foo: "bar"};
const p = new Proxy(o, {
get(target, prop, receiver) {
return prop in target ? target[prop] : "nifty!";
}
});
console.log(p.foo);
console.log(p.blarg);
Another example is the ability to hook into the various operations that get the list of properties on an object. There is no way to hook into that without Proxy. With Proxy, it's easy: You use the has trap or the ownKeys trap depending on what you want to hook into.
In terms of other use cases: Proxy is the ultimate tool for implementing the Facade pattern. Look for the use cases of Facade, and you'll find use cases for Proxy.
There is actually lots you can do with it. Theres an awesome github repo where this guy put together a bunch of proxy resources which you can check out.
https://github.com/mikaelbr/proxy-fun
Also, check out my gists, I recently started playing around with proxies, and I have a couple examples that are pretty unique. You can essentially build your own DSL using proxy and program in a closer fashion to the way you think.
https://gist.github.com/jasuperior
Proxies represent a class of dynamic programming (as in dynamic languages, not the method of problem solving) called metaprogramming, and it is absolutely not the case that anything that can be done with proxies can be done without them. In fact that's really the reason proxies exist: to enable entirely new capabilities that weren't possible before.
Proxies enable you to intercept operations on your objects that would have otherwise been purely the responsibility of the JavaScript engine; property accessing and mutating being the two obvious examples.
T.J.'s answer is a good example of something you can't do without proxies. To give you another, I am using proxies to enable singleton instances of objective entities to allow their backing data stores to be swapped-out and replaced with entirely new objects, without affecting the references that are pointing to those objects.
To do this without proxies, we would have to iterate over each field of the object and swap them out for the new fields in the new object. While it's true JavaScript is dynamic enough to allow that to be possible, Proxies allow it to be solved in a much more elegant way: the hidden backing store of the proxy is simply replaced with the new object and all future property accesses are simply directed to the new backing store rather than the old one, while external references to the object (which is actually the proxy) need be none the wiser. To them, it appears as though it is the same object (because it is), but now it happens to have completely different data behind it.
This is only one example of what you can use Proxies for. They are really quite powerful because of how dynamic they are. I'm just getting to know them, but already I can say I'm quite in love. :)
In ES6 Proxy offers the flexibility of eating your cake and having it back. You do not need to know beforehand the properties going to be get/set like in ES5.
Now with ES6 Proxy you can add new property to an object like so: proxyObj.newProp = 9, Proxy will smile and set the new property without prejudice.
I'm using a js API and I have to instantiate a class that requires a <div> element in its constructor. However this is only used by the class to do some rendering in the element and I don't need it, I just want to use a method of this class.
I came up with this which seems better than linking to a random <div> element of the page :
service = new API.service(document.createElement("div"));
service.useMethod();
Do you have any better ideas about how to do this ? I don't really know what is good practice in this case.
FYI the class I'm actually using is google.maps.places.PlacesService from Google maps javascript API in order to use the method getDetails on some info I retrieved earlier.
Your approach is OK (I don't know a better approach).
But the issue:
This required node isn't there for fun, the API will print there Copyright-details for the requests(if there are any), and these details must be visible(at least when you display something that is based on the data returned by the service).
So your approach is correct from a programmers view, but it would violate the TOS
Dojo for instance adds a member to a JS object called "declared_class". I would like to find those and replace some stuff. And, can this be done also outside of Dojo ? I know, JS is not type oriented but you never know whats out to bypass this lack of introspection facilities.
Update : This is NOT about DOM objects. I am writing a sort of real-time Javascript editor. After I reloaded the script, I need to locate related (Dojo modules) objects and mixin altered functions only.
Update 2 : It doesn't seem to be possible without a prototype or a similar patch. Since all the code is running 1:1 in a node instance as well, I am wondering whether I can determine those objecys in a node.js instance ?
I have a web application based on apache. php, js and jquery. All works fine.
On the client side there is a small library in JS/jquery, offering some generic list handling methods. In the past I used callbacks to handle those few issues where those methods had to behave slightly different. That way I can reuse methods like list handling, dialog handling and stuff for different part of the application. However recently the number of callbacks I had to hand through when stepping into the library grew and I am trying a redesign:
Instead of specifying all callbacks as function arguments I created a central catalog object in the library. Each module of the application registers its own variant of callbacks into that catalog upon initialization. At runtime the methods lookup the required callbacks in that catalog instead of expecting it specified in their list of arguments. This cleans up things quite a lot.
However I have one thing I still cannot get rid of: I require a single argument (I call it context, mode might be another term) that is used by the methods to lookup the required callback in the catalog. This context has to be handed through to all methods. Certainly better than all sorts of different callbacks being specified everywhere, but I wonder if I can get rid of that last one to.
But where do I specify that context, if not as method argument ? I am pretty new to JS and jquery, so I failed to find an approach for this. Apparently I don't want to use global vars, and to be frank I doubt that I can simply store a context in a single variable anyway, since because of all the event handlers and external influences methods might be called in different contexts at the same time, or at least interleaving. So I guess I need something closer to a function stack. Maybe I can simply push a context object to the stack and read that from within the layers of the library that need to know ? The object would be removed when I leave the library again. Certainly other approaches exist too.
Here are so many experienced coders how certainly can give a newbie like a short hint, a starting point that leads to an idea, how to implement this. How is such thing 'usually' done ?
I tried round a while, exploring the arguments.callee.caller hierarchy. I thought maybe I could set a prototype member inside a calling function, then, when execution steps further down I could simply traverse the call stack upwards until I find a caller holding such property and use that value as context.
However I also saw the ongoing discussions that reveal two things: 1.) arguments.callee appears to be depreciated and 2.) it appears to be really expensive. So that is a no go.
I also read about the Function.caller alternative (which appears not to be depreciated and much more efficient, however until now I failed to explore that trail...
As written currently passing the context/mode down simply works by specifying an additional argument in the function calls. It carries a unique string that is used as a key when consulting the catalog. So something like this (not copied, but written as primitive example):
<!-- callbacks -->
callback_inner_task_base:function(arg1,arg2){
// do something with args
}
callback_inner_task_spec:function(arg1,arg2){
// do something with args
}
<!-- catalog -->
Catalog.Callback:function(context,slot){
// some plausibility checks...
return Catalog[context][slot];
}
Catalog.base.slot=callback_inner_task_base;
Catalog.spec.slot=callback_inner_task_spec;
<!-- callee -->
do_something:function(arg1,arg2,context){
...
// callback as taken from the catalog
Catalog.Callback(callback,'inner_task')(arg1,arg2);
...
}
<!-- caller -->
init:function(...){
...
do_something('thing-1',thing-2','base');
do_something('thing-1',thing-2','spec');
...
}
But where do I specify that context, if not as method argument ?
Use a function property, such as Catalog.Callback.context
Use a monad
I am working on an old code base which uses dojo datagrid and JsonRestStore, using declarative approach(in HTML). I am now trying to adapt this to use the newer dojo.store.JsonRest .
When I declare the JsonRest and ObjectStore in HTML, it works.
I want to use json.store.Cache as my store, with dojo.store.JsonRest and dojo.store.Memory backing it.
The constructor for json.store.Cache takes two arguments.
a) Is there a possibility to define constructor arguments in HTML declarative style?
I didn't want to touch the (declarative) code of the Datagrid so I tried setting the store of the Grid in dojo.addOnLoad . I get a weird error in Firebug for dojo.js line 402 which is actually a comment:
// 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result.
My guess is that the error has nothing to do with dojo.js at all and the exception actually occurred in a closure somewhere(I think I've seen this before).
b) Is it possible to mix and match Declarative and Programmatic style in this way? And if yes, what event should I be setting the grid's store on?
I'm answering this myself as I figured it out later. There seems to be no problem in mixing and matching the declarative and programmatic style.
I changed from using dojo.addOnLoad to dojo.ready , but I don't think that was the problem anyway.
I was trying to set the datagrid's query in a call to datagrid.setQuery and then setting the store with datagrid.setStore. It didn't work no matter which order I tried in(query first or store first).
Turns out both have to be set together in the call to setStore. The method accepts the query as its second parameter.
This solved my problem.