Trying to use ES6 classes in WebStorm 8/9 and getting this error when I add a getter:
'use strict';
(function () {
class Collection {
constructor(resource) {
this._models = [];
this._resource = resource;
}
fetch() {
this._models = this._resource.query();
}
get models() {
return this._models;
}
}
})();
Moving the class definition outside the anonymous function removes the error, but this isn't an option.
I disabled all inspections and intentions in the preferences. Any ideas how to remove/suppress this message?
WEB-13447 is fixed in webStorm 10. Please try WebStorm 10 RC
Related
I am trying to add a mixin in Magento 2 for the checkout/payment page shipping info section.
There is an existing section in vendor/magento/module-checkout/view/frontend/web/template/shipping-information/address-renderer/default.html as follows:
<each args="data: address().customAttributes, as: 'element'">
<text args="$parent.getCustomAttributeLabel(element)"/>
<br/>
</each>
I want to create a myNewFunction() and call it from here. So, I have temporarily added if="$parent.myNewFunction(element)" to it, like this:
<each args="data: address().customAttributes, as: 'element'">
<text if="$parent.myNewFunction(element)" args="$parent.getCustomAttributeLabel(element)"/>
<br/>
</each>
That pre-existing function getCustomAttributeLabel is defined in vendor/magento/module-checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js.
This is where I need to add my myNewFunction() at. I don't want to override that entire file and duplicate it into my theme, so I am trying to add the function to it via mixin.
To do this, I have stubbed out a module: app/code/MyCompany.
In this module, I have created:
app/code/MyCompany/Checkout/view/frontend/requirejs-config.js
with this code:
var config = {
config: {
mixins: {
'Magento_Checkout/js/view/shipping-information/address-renderer/default': {
'MyCompany_Checkout/js/view/shipping-information/address-renderer/default-mixin': true
}
}
}
};
Then I created the mixin itself in:
app/code/MyCompany/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default-mixin.js
with this code:
define([
'uiComponent',
'underscore',
'Magento_Customer/js/customer-data'
], function (Component, _, customerData) {
'use strict';
return function (target) {
return target.extend({
myNewFunction: function (element) {
console.log(element);
return false;
}
});
}
});
I currently have deploy mode set to "development" in Magento. Nonetheless, I have tried removing all the var/* files, generating static content again, and clearing the cache, for good measure.
No matter what, upon loading the checkout/payment page, I keep getting this JS error in the console:
$parent.myNewFunction is not a function
What am I doing wrong here?
I suspected the module needs to have a register.php? Or the module is not loading? Yet, I have seen plenty of other examples such as this guide, this Magento mixin stackoverflow question, and this example on how to add shipping.js functionality via mixin, none of which mention doing anything more with the module other than declaring the requirejs-config.js and the mixin JS file itself.
Just found a way to override that function using 'mixins'.
On requirejs-config.js file I had to add:
config: {
mixins: {
'Magento_Checkout/js/view/shipping': {
'Mynamespace_Mymodule/js/view/shipping': true
}
}
}
For the following JavaScript code, how can I write it in ReasonML?
class HelloWorld extends HTMLElement {
constructor() {
super();
// Attach a shadow root to the element.
let shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `<p>hello world</p>`;
}
}
I could not find any documentation on writing classes in ReasonML? I cannot use plain objects/types as I need to extend from HTMLElement class which doesn't work with ES style classes.
I have looked into this existing question - How to extend JS class in ReasonML however, it is a different thing. To write web component, we need to extend HTMLElement and must call it with new keyword. ES5 style extension mechanism doesn't work.
You can't. Not directly at least, since BuckleScript (which Reason uses to compile to JavaScript) targets ES5 and therefore has no knowledge of ES6 classes.
Fortunately, ES6-classes require no special runtime support, but are implemented as just syntax sugar, which is why you can transpile ES6 to ES5 as shown in the question you link to. All you really have to do then, is to convert this transpiled output into ReasonML:
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var BaseElement = (function (_super) {
__extends(BaseElement, _super);
function BaseElement() {
_super.call(this);
}
return BaseElement;
}(HTMLElement));
And depending on what specific class-features you actually need, you can probably simplify it a bit.
I'm using IntelliJ IDEA's File Watcher to automatically compile the TypeScript files, but for some reason it's not liking classes defined within blocks / function closures:
Is there a way around this without having to move everything to the top-level / global scope?
Using the following code in TypeScript results in practically the same JavaScript that you appear to be aiming for...
namespace MY_NAMESPACE {
export class AssetService {
}
}
Resulting code:
var MY_NAMESPACE;
(function (MY_NAMESPACE) {
var AssetService = (function () {
function AssetService() {
}
return AssetService;
}());
MY_NAMESPACE.AssetService = AssetService;
})(MY_NAMESPACE || (MY_NAMESPACE = {}));
If you want to really reduce the scope, switch to external modules (AKA "modules" these days).
If you don't export the class from the module/file, it won't be visible globally, i.e. there's no reason to enclose class definitions in function scopes.
More about modules in TS: https://www.typescriptlang.org/docs/handbook/modules.html
someone knows how to turn off the global scope in XText 2.9? I want to turn off the global scope in order to only can access the elements of the files that I import. For example:
file1.mydsl:
element A(C){
;
}
subelement C{
;
}
file2.mydsl:
element B(C){
;
}
This should return an error in file2.mydsl because I haven't imported "file1.mydsl". I should add the line - import "file1.mydsl" - to avoid the error. How can I do that in Xtext 2.9? I have a working code that does what I want but the code uses Xtext 2.8 and doesn't work on 2.9 version.
hi you can still switch to importURI based scoping
https://bugs.eclipse.org/bugs/show_bug.cgi?id=491110
fragment = org.eclipse.xtext.generator.adapter.FragmentAdapter {
fragment = org.eclipse.xtext.generator.scoping.ImportURIScopingFragment {}
}
or simply by adding the bindings manually
class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
override bindIGlobalScopeProvider() {
importuriglobalscopeprovider
}
override configureIScopeProviderDelegate(Binder binder) {
binder.bind(IScopeProvider).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE))
.to(SimpleLocalScopeProvider);
}
}
I'm new to TypeScript but have a background in C# and I'm a little bit confused about how to handle TypeScript modules. I've been thinking about modules as namespaces in C# but maybe this is wrong because my code doesn't behave the way I was expecting.
I have the following folder structure:
|-myApp
| |-myController
| | |-myController.ts
| |-models
|-a.ts
|-b.ts
and this code:
// a.ts
module MyApp.Models {
export class A {
}
}
// b.ts
module MyApp.Models {
export class B {
}
}
// myController.ts (THIS DOESN'T WORK)
module MyApp.MyController {
import Models = MyApp.Models;
class MyController {
a = new Models.A();
b = new Models.B();
}
}
// myController.ts (THIS WORKS)
module MyApp.MyController {
class MyController {
a = new Models.A();
b = new Models.B();
}
}
In the example above my attempt at importing the module (namespace?) Models will result in an error at runtime because Models is undefined. However if I remove the import-statement the code will works just fine. I'm probably not thinking clearly and doing some really stupid beginners mistake but could someone please tell me what I'm doing wrong and what the best way to use modules in my particular scenario would be. Why does it work if I remove the import but not with it?
Regards Kristofer
Sorry for late answer.
Problem and magic around modules/namespaces are occurred in three things:
Your system - due to your system TypeScript compiler discover files by difference ways, and when it compile your source code to JS code it take a place, because the same ts files provide different results JS.
Understanding magic statement /// <reference path="***"/>. It is very important use this word if there are no additional Module System like AMD, or System.js, etc. Because if you use merged compilation it take place, because it tell compiler in what order it should compile files.
Understanding of JS execution and structure that TypeScript propose in compiled JS file. Just consider next example - (it is your compiled into JS example)
var MyApp;
(//functon wrapping
function (MyApp) {//function declaration
var MyController;
(function (MyController_1) {
var Models = MyApp.Models;
var MyController = (function () {
function MyController() {
this.a = new Models.A();
this.b = new Models.B();
}
return MyController;
})();
MyController_1.MyController = MyController;
})(MyController = MyApp.MyController || (MyApp.MyController = {}));
}
)(MyApp || (MyApp = {}));// end of function wrapping and it execution
/// <reference path="myApp/MyController/myController.ts"/>
new MyApp.MyController.MyController(); // createing new instance of MyController
var MyApp;
(function (MyApp) {
var Models;
(function (Models) {
var B = (function () {
function B() {
}
return B;
})();
Models.B = B;
})(Models = MyApp.Models || (MyApp.Models = {}));
})(MyApp || (MyApp = {}));
var MyApp;
(function (MyApp) {
var Models;
(function (Models) {
var A = (function () {
function A() {
}
return A;
})();
Models.A = A;
})(Models = MyApp.Models || (MyApp.Models = {}));
})(MyApp || (MyApp = {}));
//# sourceMappingURL=app.js.map
if you dive deeper into JS you would find that the JS code is executing in the next order
Reading function and passing it into the memory
Executing another code
That is why the next code would work
myFunction();
function myFunctuion(){};
Due to typescript JS building technics for modules and classes it use anonimous function like this:
var MyApp;
(//functon wrapping
function (MyApp) {//function declaration
var MyController;
(function (MyController_1) {
var Models = MyApp.Models;
var MyController = (function () {
function MyController() {
this.a = new Models.A();
this.b = new Models.B();
}
return MyController;
})();
MyController_1.MyController = MyController;
})(MyController = MyApp.MyController || (MyApp.MyController = {}));
In this case calling like next cause runtime exception, because anonimus block has not executed before.
MyController(); // here runtime exception
var MyController = (function () {
function MyController() {
this.a = new Models.A();
this.b = new Models.B();
}
return MyController;
})();
Now, back to the our example and discover it, as you see MyController defined earlier, than we do execution of anonymous function and variable with name MyController now exist in the global scope.
The next step is executing constructor of MyController class, in it we find next two part of code
this.a = new Models.A();
this.b = new Models.B();
But here we get an error because the anonymous function that consist variable Modules and classes A and B has not executed yet. That is why, in this moment we getting the error that variable Modules is undefined.
I hope that this topic make your knowledge about JS and TS better, and help you in your new features!!!
Good Luck!
P.S. Here is working example
Typescript modules are similar to C# namespaces. They help organize the codebase.
The import statement can be used for two things: to provide an alias or to import external modules.
To create an alias you use the import as you did:
import Models = App.Models;
To import an external module you use:
import Models = './path/to/module';
I can't figure out why your code doesn't work. I tried to reproduce it on my machine but both controllers work for me.