"OOP" JavaScript does not work

Hi!

I figured that I could try to make my code work like “OOP” JavaScript (based on http://www.phpied.com/3-ways-to-define-a-javascript-class) to keep it more tidy as I am concatenating it since this is what Fuse seems to like the most.

But I am getting some strange errors, so I made a test-case:

<!-- MainView.ux -->
<App Theme="Basic">
    <JavaScript File="js.js" />

    <StackPanel>
        <Text Value="{hei}" TextAlignment="Center"/>
        <Button Text="Hade" Clicked="{hade}" />
    </StackPanel>
</App>

//js.js
var Observable = require("FuseJS/Observable");

var test = new function() {
    this.hei = Observable("hei");
    this.hade = function() {
        console.log(this.hei.value);
    }
}

module.exports = {
    "hei": test.hei,
    "hade": test.hade
}

I have also tried using ES6 classes transpiled through babel without luck. It didn’t return an error, but I could not manage to refer to the variables. Example:

let Observable = require('FuseJS/Observable');

export class test {
  construct() {
    this.hei = Observable("Hei");
  }

  hade() {
      this.hei.value = "hade";
  }
}

Is this or any of the examples in the article at all supposed to work? It would be great with support for this as it’s really helpful for avoiding duplicate variables and stuff like that.

What error messages are you getting?

    Name: TypeError
    ErrorMessage: undefined cannot be converted to an object
    FileName: C:\Users\joehol\Documents\Fuse\js-test\js.js
    LineNumber: 6
    JS StackTrace: TypeError: undefined cannot be converted to an object
        at anonymous (C:\Users\joehol\Documents\Fuse\js-test\js.js:6)

And what does line 6 say?

Line #6 is console.log(this.hei.value);.

Hi,

with doing things the OOP-ish way, you will need to add an ux:Global attribute to the JavaScript tag, and then do what you want with the data, and finally export it to where you are using it, like so:

<App Theme="Basic">
    <JavaScript File="js.js" ux:Global="JSFile" />
    <JavaScript>
        var jsFile = require('JSFile');
        module.exports = {
            hei: jsFile.hei
        }
    </JavaScript>
    <Panel>
        <Text Value="{hei}" />
    </Panel>
</App>

Bear in mind that you can only access values, not make calls or invocations to Javascript from; those will need a JavaScript tag to do class/function instantiation, processing, etc. and export the value to the UX scope—so that in your UX code you will only need to care about how to display your data that’s exported.

In regards to the ES6 example you have, where you export the class, the issue might be caused if Babel does not result in CommonJS modules, that have explicitly exports set to the module object.

From looking how Babel transpiles ES6 modules, it’s implicitly depending for the module object being global, so doing:

let Observable = require('FuseJS/Observable');

export class TestClass {
  construct() {
    console.log('new class');
  }
}

…actually ends up (just picking out the relevant parts from the transpile) like this:

var Observable = require('FuseJS/Observable');

var TestClass = (function () {
  function TestClass() {
    _classCallCheck(this, TestClass);
  }

  _createClass(TestClass, [{
    key: 'construct',
    value: function construct() {
      console.log('new class');
    }
  }]);

  return TestClass;
})();

exports.TestClass = TestClass;

And this implicit usage of exports seems to be one cause or error in the transpiled code. exports is undefined, while it’s expected to be an object, and trying to set properties to something that’s undefined will result in an error.

To add to the Babel transpiling case, what slipped past me was the typo you had in the ES6 class example, where the class’ constructor had a typo in it; instead of construct, it needs to be constructor.