Not sure if I need to add another jshint library or if I should do this a different way.
I have a file (for explanations reasons we'll call it stuff-functions.js) that exports functions like this...
export function a() {
return 'stuff';
}
export function b() {
return 'more stuff';
}
export function c() {
return 'even more stuff';
}
In another file I'm importing that file and calling that function by an argument...
import * as stuffFunctions from './stuff-functions'
export default class someReactClass {
myFunc(functionToCall) {
return stuffFunctions[functionToCall]();
}
...
}
It works fine, but in the console I'm getting an eslint error...
Unable to validate computed reference to imported namespace 'stuffFunctions'
So, should I go about this differently or hunt down some sort of eslint library that allows for this?
EDIT...
I've added this line to stop the error // eslint-disable-line
I was just curious if there was a better way to do this. Maybe something like...
import {a, b, c} from './stuff-functions';
export default class someReactClass {
myFunc(functionToCall) {
const myStuffFunctions = {
a: a,
b: b,
c: c
};
return myStuffFunctions[functionToCall]();
}
...
}
Seems redundant though. :/
The error is being reported by the import/namespace rule in the eslint-plugin-import plugin. It's occurring because you are deciding which imported function will be called at runtime:
stuffFunctions[functionToCall]();
The plugin's static analysis cannot verify that this is a valid import and it reports it as an error.
The simplest solution would be to add an ESLint comment to reconfigure the rule to allow computed references:
/*eslint import/namespace: ['error', { allowComputed: true }]*/
import * as stuffFunctions from './stuff-functions'
export default class someReactClass {
myFunc(functionToCall) {
return stuffFunctions[functionToCall]();
}
...
}
Related
I have some JS files which I want to format nicer with a CLI formatter tool like Prettier. I tried Prettier itself, but I was surprised to find that it doesn't add blank lines between function definitions. I think this would enhance visual structure significantly.
An example might clarify what I'm after. Given the input source code:
import {foo, bar} from "./myfoobar.js"
export var myfirstfunc = function (para) {
...
}
// mysecondfunc does wonderful things
export var mysecondfunc = function (more, para) {
...
}
I would like to see the following output code with blank lines:
import {foo, bar} from "./myfoobar.js"
export var myfirstfunc = function (para) {
...
}
// mysecondfunc does wonderful things
export var mysecondfunc = function (more, para) {
...
}
In my test Prettier doesn't do this. Is there a way to tell Prettier -- or another formatter -- to do this kind of visual structuring?
You can achieve something similar to this by using ESLint's padding-line-between-statements rule. Any sort of STATEMENT_TYPE (such as export, import, var) can be specified to require a blank line between it and another given STATEMENT_TYPE (or wildcard, to match anything).
The following config:
padding-line-between-statements: [
"error",
{ blankLine: "always", prev: "export", next: "*" },
{ blankLine: "always", prev: "import", next: "*" },
{ blankLine: "always", prev: "var", next: "*" },
]
results in automatically fixed code of:
import {foo, bar} from "./myfoobar.js"
export var myfirstfunc = function (para) {
}
// mysecondfunc does wonderful things
export var mysecondfunc = function (more, para) {
}
Demo
Any IDE that supports ESLint's auto-fixing (such as VSCode) should be able to implement this.
Feel free to tweak with the config settings objects to require spaces between different types of statements as desired.
I am learning cypress and javascript and have come across this type error.
TypeError: _testElements.default.selectionRow is not a function
I looked at some documentation with cypress and can't see a mistake I am making in the code, so was hoping someone with javascript and cypress experience may know why this error is being outputted.
Code:
First the class where it gets the element:
class testElements {
selectionRow() {
return cy.get('.selectionRow')
}
typeButton() {
return cy.get('.typeButton')
}
}
export default testElements
And then the code it's referring the error to is below:
import { Given, When, Then } from "cypress-cucumber-preprocessor/steps";
import testElements from '../elements/testElements';
When ("User selects a row", () => {
testElements.selectionRow()
.within(() => {
testElements.typeButton().not(".disabled");
})
})
You should first create a class instance to use the methods:
const testElem = new testElements();
testElem.selectionRow()
And I suggest to use uppercase name convention for class TestElements.
If you don't want to instantiating the class, you can use static methods
I have created a module greatings.js like this one:
function greatings() {
this.hello = function() {
return 'hello!';
}
this.goodbye = function() {
return 'goodbye!';
}
}
module.exports = greatings;
Then I imported it into main.js in VUE.JS just like:
import greatings from './assets/js/greatings';
Vue.use(greatings);
Now I would like to use it in my components but if I do it I got an error:
mounted() {
this.greatings.hello();
}
ERROR: Error in mounted hook: "TypeError: Cannot read property 'hello' of undefined"
How to fix it and be able to use my greatings?
Thanks for any help!
greatings.js file should be like this
export default {
hello() {
return "hello";
},
goodbye() {
return "goodbye!";
}
};
and import in any file you want to use like this
import greatings from './assets/js/greatings';
and call any function do you want. remove this function Vue.use(greatings);
When using Vue.use() to register a custom plugin, it has to define an install() function, which is called by Vue. From docs:
A Vue.js plugin should expose an install method. The method will be called with the Vue constructor as the first argument, along with possible options.
See the provided example, for all the options you have when creating a custom plugin: https://v2.vuejs.org/v2/guide/plugins.html
I've some problem, in my project I need to add Sanitize.js on my project, I've copied to my own 3rd party folder ex vendor
to import it I'm using
import {san} from '../../vendor/Sanitize' //There's No error when compiling this one
but there's an error when I run the page, I'm trying to call the function from Sanitize.js as in readme saying to use it just do like this
var s = new san.Sanitize({
elements: ['a', 'span'],
attributes: {
a: ['href', 'title'],
span: ['class']
},
protocols: {
a: { href: ['http', 'https', 'mailto'] }
}
});
s.clean_node(p);
The Error is
san.Sanitize is not a function/ class constructor
Any idea why this is happening? or did I miss something? There's no Error in compiling process, the error only occurs when I try to run the web page,
Because Sanitize.js is not a module.
Maybe you can try the following solution:
Add export default Sanitize; in end of sanitize.js.
Use import Sanitize from "./sanitize"; to import it.
Remove the following code from sanitize.js.
if ( typeof define === "function" ) {
define( "sanitize", [], function () { return Sanitize; } );
}
I have a helper method that maps a number to a text -
Ember.Handlebars.helper('getStatusText', function (value, options) {
switch(value) {
case 1: return "Fresh";
break;
case 2: return "Callback";
break;
default: return "Unable to get Status";
}
});
I am able to use the helper in the view by using {{getStatusText 1}}
But how do I use the helper in an action inside an ObjectController ?
Test.DealController = Ember.ObjectController.extend({
selectedStatusType: null,
statusList: ["Fresh","Callback"],
actions: {
updateStatus: function(deal) {
// How do I call the handlebars helper here ?
console.log({{getStatusText 1}});
}
},
});
this obviously does not work.
What are the other ways ??
For better understanding, here is the jsbin
With ember-cli it can be done like this:
// helpers/foo.js
export function foo(params) {
return params;
}
export default Ember.Helper.helper(foo);
Helper foo exports a function (containing the helper logic) and the function wrapped in an Ember helper (for use in a template).
// helpers/bar.js
import { foo } from '<project>/helpers/foo';
export function bar(params) {
return foo(params);
}
export default Ember.Helper.helper(bar);
Helper bar imports the helper function from foo and uses it in it's own template helper.
Pull the logic out of the helper, making it available to be called both by the helper, and by non handlebars helper items alike. Parsing it into handlebars template and evaluating it is over complicating it.
Where you put it is up to you, you could namespace it to your app, or just create it as a function that lives with your helper.
function getStatusText(value){
switch(value) {
case 1: return "Fresh";
break;
case 2: return "Callback";
break;
default: return "Unable to get Status";
}
}
Ember.Handlebars.helper('getStatusText', function (value, options) {
return getStatusText(value);
});
http://emberjs.jsbin.com/cenep/1/edit
Most helpers are simple. In this case, exporting a vanilla function is the way to go. Pass the function exactly the data it needs.
Ember also has class-based helpers for a more complex use case. They can leverage other container dependencies. You can still have a class-based helper's compute method call your exported vanilla function.
However, the parameter list to the function could get unwieldy for other callers.
import Helper from 'ember-helper';
import service from 'ember-service/inject';
export function vanillaFunction(imageService, userService, foo, bar, baz, dependency3, options) {
...
}
export default Helper.extend({
imageService: service('image'),
userService: service('user'),
compute(positionalParams, hashParams) {
return vanillaFunction(this.get('imageService'), this.get('userService'), positionalParams[0], positionalParams[1], ...);
},
});
To benefit from container lookups, rather than call the vanilla function, you can manually instantiate such a helper and call compute yourself. This is rare. But it benefits from a small interface, uniform with how you'd call it in the template. The helper is normally instantiated by HTMLBars for use within a template, which has special context and observation rules. So there's a little hoop jumping to use it inside your e.g. controller.
import Controller from 'ember-controller';
import getOwner from 'ember-owner/get';
import setOwner from 'ember-owner/set';
export default Controller.extend({
someMethod() {
const owner = getOwner(this);
const helperFactory = owner.resolveRegistration('helper:my-helper');
const helperInstance = helperFactory.create();
setOwner(helperInstance, owner); // I'm not sure why the factory doesn't do this for you
return helperInstance.compute([1]); // "Fresh"
},
});