I have this code here:
getData(value, index) {
const {responseMetadata, responseData} = this.getResponseDatum();
return responseData.get(index).get('code').toUpperCase();
}
eslint reports an error:
19:12 "responseMetadata" is defined but never used
In python I can silent this kind of error by renaming the variable to _responseMetadata. Is there a Equivalent in es6?
If you don't need the variable, just don't create it:
const {responseData} = this.getResponseDatum();
A destructuring assignment doesn't need to match all properties of the returned object.
In your case, since you need only one property and don't use it multiple times, there's actually not much reason to use destructuring or a variable at all:
getData(value, index) {
return this.getResponseDatum().responseData.get(index).get('code').toUpperCase();
}
You can turn off a rule for a section of code. See http://eslint.org/docs/user-guide/configuring.html#configuring-rules
/*eslint-disable */
//suppress all warnings between comments
alert('foo');
/*eslint-enable */
Related
I keep seeing functions that look like this in a codebase I'm working on:
const func = ({ param1, param2 }) => {
//do stuff
}
What exactly is this doing? I'm having a hard time finding it on google, because I'm not even sure what this is called, or how to describe it in a google search.
It is destructuring, but contained within the parameters. The equivalent without the destructuring would be:
const func = o => {
var param1 = o.param1;
var param2 = o.param2;
//do stuff
}
This is passing an object as a property.
It is basically shorthand for
let param1 = someObject.param1
let param2 = someObject.param2
Another way of using this technique without parameters is the following, let's consider then for a second that someObject does contain those properties.
let {param1, param2} = someObject;
It is an object destructuring assignment. Like me, you may have found it surprising because ES6 object destructuring syntax looks like, but does NOT behave like object literal construction.
It supports the very terse form you ran into, as well as renaming the fields and default arguments:
Essentially, it's {oldkeyname:newkeyname=defaultvalue,...}. ':' is NOT the key/value separator; '=' is.
Some fallout of this language design decision is that you might have to do things like
;({a,b}=some_object);
The extra parens prevent the left curly braces parsing as a block, and the leading semicolon prevents the parens from getting parsed as a function call to a function on the previous line.
For more info see:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Beware, key errors during object destructuring assignment do NOT throw; you just end up with "undefined" values, whether it's a key error or some other error that got silently propagated as 'undefined'.
> var {rsienstr: foo, q: bar} = {p:1, q:undefined};
undefined
> foo
undefined
> bar
undefined
>
I have the following function that is setting up a select2 plugin, which needs selects to stay open if they are multiple but closed if they are not:
function setUpSelects($selects, closeOnSelect) {
$selects.each((i, item) => {
const $item = $(item);
$item.select2({
closeOnSelect: closeOnSelect, // <-- error on this line
minimumResultsForSearch: Infinity,
placeholder: $item.data('placeholder') || $item.attr('placeholder'),
});
});
}
setUpSelects($('select:not([multiple])'), false);
setUpSelects($('select[multiple]'), true);
However, when I try to run this code, the eslint checker is giving me an error (on the line shown above) of:
error Expected property shorthand object-shorthand
I have done a search and read the docs but it doesn't show how you are meant to use a variable and the unaccepted answer on this question seems to think it may be a bug in eslint (although I have found no evidence to support that)
Is there a way to make this work or should I just disable the rule for that line?
An excerpt from eslint regarding the issue:
Require Object Literal Shorthand Syntax (object-shorthand) - Rule Details
This rule enforces the use of the shorthand syntax. This applies to
all methods (including generators) defined in object literals and any
properties defined where the key name matches name of the assigned
variable.
Change
closeOnSelect: closeOnSelect
to just
closeOnSelect
This rule checks that object literal shorthand syntax is used, e.g {a, b} instead of {a: a, b: b}. The rule is configurable, see options for more details.
Despite this shorthand syntax is convenient, in some cases you may not want to force it usage. You can disable the check in your config:
// .eslintrc.json
{
"rules": {
// Disables the rule. You can just remove it,
// if it is not enabled by a parent config.
"object-shorthand": 0
}
}
In case of TSLint there is a different option:
// tslint.json
{
"rules": {
// Disables the rule. You can just remove it,
// if it is not enabled by a parent config.
"object-literal-shorthand": false
}
}
Wants to define Object with keys and can't use any. Try this.
interface Map {
[key: string]: string | undefined
}
const HUMAN_MAP: Map = {
draft: "Draft",
}
export const human = (str: string) => HUMAN_MAP[str] || str
I spent hours looking at this piece of code:
1: const { services, lists } = this.props;
2:
3: const List = _.map(lists.list, (list) => {
4: const services = _.filter(services.list, (service) => lists.services.indexOf(service.id) > -1);
5: ...
120: ...
121: });
At line number 4, I get an error:
Cannot read property list of undefined
At line number 4, property list is being referenced by services, apparently. And, it is undefined. But, at line 1, it's defined which can be checked by logging its value.
I know the value of services becomes undefined in the closure because JS has its way of finding the variable declarations first and assigning undefined to them before executing the given function. My concern is that, should it be the behavior with the given piece of code considering it's being pre-compiled using Babel?
Edit: I realized that this was your actual question:
My concern is that, should it be the behavior with the given piece of code considering it's being pre-compiled using Babel?
The answer is no, Babel's job is to convert code into its older equivalent, the equivalent here being a var statement. The const statement you have there is perfectly valid syntactically, but is destined to throw an error semantically (note: if you actually executed that const statement in an environment that supports const, it would throw an error before you even tried to access service's list property).
Original answer:
If you define a variable in the same line that you use it, it will always be undefined the first time the statement tries to access it, even if there's a variable with the same name in an outer scope:
const a = 2;
function f() {
const a = a + 1; // error
console.log(a);
}
f();
The solution: don't reuse variable names in inner scopes. Just come up with new names for your variables:
const filteredServices = _.filter(services.list, (service) => lists.services.indexOf(service.id) > -1);
I wanted to shorten an object literal in ES6 like this:
const loc = this.props.local;
The reason is loc.foo(); is a lot easier to type than this.props.local.foo();
But now ESLint complains:
Use object destructuring: prefer-destructuring
I've read the error description on eslint.org but I don't understand it. They have an example which looks very similar to my code but theirs seem to be ok?
var foo = object.bar;
How can I fix the error without setting it to ignore in the .eslintrc file?
change your code from:
const local = this.props.local;
to:
const { local } = this.props;
They are equivalent and you can call local.foo() in the same way. except that the second use object destructuring.
It's a new construct in ES 6 that allows you to match property of an object in assignment. The syntax you need is:
const { local: loc } = this.props
which translates to: "declare a constant loc and assign it the value of property local from this.props".
It's telling you to use
const {props: {local: loc}} = this;
This question already has answers here:
Are there constants in JavaScript?
(33 answers)
Closed 6 years ago.
I want to declare string constants in JavaScript.
Is there is a way to do that?
Many browsers' implementations (and Node) have constants, used with const.
const SOME_VALUE = "Your string";
This const means that you can't reassign it to any other value.
Check the compatibility notes to see if your targeted browsers are supported.
Alternatively, you could also modify the first example, using defineProperty() or its friends and make the writable property false. This will mean the variable's contents can not be changed, like a constant.
Are you using JQuery? Do you want to use the constants in multiple javascript files? Then read on. (This is my answer for a related JQuery question)
There is a handy jQuery method called 'getScript'. Make sure you use the same relative path that you would if accessing the file from your html/jsp/etc files (i.e. the path is NOT relative to where you place the getScript method, but instead relative to your domain path). For example, for an app at localhost:8080/myDomain:
$(document).ready(function() {
$.getScript('/myDomain/myScriptsDir/constants.js');
...
then, if you have this in a file called constants.js:
var jsEnum = { //not really an enum, just an object that serves a similar purpose
FOO : "foofoo",
BAR : "barbar",
}
You can now print out 'foofoo' with
jsEnum.FOO
There's no constants in JavaScript, but to declare a literal all you have to do is:
var myString = "Hello World";
I'm not sure what you mean by store them in a resource file; that's not a JavaScript concept.
Of course, this wasn't an option when the OP submitted the question, but ECMAScript 6 now also allows for constants by way of the "const" keyword:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
You can see ECMAScript 6 adoption here.
Standard freeze function of built-in Object can be used to freeze an object containing constants.
var obj = {
constant_1 : 'value_1'
};
Object.freeze(obj);
obj.constant_1 = 'value_2'; //Silently does nothing
obj.constant_2 = 'value_3'; //Silently does nothing
In strict mode, setting values on immutable object throws TypeError. For more details, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
Well, you can do it like so:
(function() {
var localByaka;
Object.defineProperty(window, 'Byaka', {
get: function() {
return localByaka;
},
set: function(val) {
localByaka = window.Byaka || val;
}
});
}());
window.Byaka = "foo"; //set constant
window.Byaka = "bar"; // try resetting it for shits and giggles
window.Byaka; // will allways return foo!
If you do this as above in global scope this will be a true constant, because you cannot overwrite the window object.
I've created a library to create constants and immutable objects in javascript. Its still version 0.2 but it does the trick nicely. http://beckafly.github.io/insulatejs
Starting ECMAScript 2015 (a.k.a ES6), you can use const
const constantString = 'Hello';
But not all browsers/servers support this yet. In order to support this, use a polyfill library like Babel.
So many ways to skin this cat. You can do this in a closure. This code will give you a read-only , namespaced way to have constants. Just declare them in the Public area.
//Namespaced Constants
var MyAppName;
//MyAppName Namespace
(function (MyAppName) {
//MyAppName.Constants Namespace
(function (Constants) {
//Private
function createConstant(name, val) {
Object.defineProperty(MyAppName.Constants, name, {
value: val,
writable: false
});
}
//Public
Constants.FOO = createConstant("FOO", 1);
Constants.FOO2 = createConstant("FOO2", 1);
MyAppName.Constants = Constants;
})(MyAppName.Constants || (MyAppName.Constants = {}));
})(MyAppName || (MyAppName = {}));
Usage:
console.log(MyAppName.Constants.FOO); //prints 1
MyAppName.Constants.FOO = 2;
console.log(MyAppName.Constants.FOO); //does not change - still prints 1
You can use freeze method of Object to create a constant. For example:
var configObj ={timeOut :36000};
Object.freeze(configObj);
In this way you can not alter the configObj.
Use global namespace or global object like Constants.
var Constants = {};
And using defineObject write function which will add all properties to that object and assign value to it.
function createConstant (prop, value) {
Object.defineProperty(Constants , prop, {
value: value,
writable: false
});
};
Just declare variable outside of scope of any js function. Such variables will be global.