Error running AngularJS ES6 - html

I'm trying to run a simple AngularJS example using the latest ES6 syntax in html. Here's my html code:
<!DOCTYPE html>
<html>
<head>
<title>Basic Angular JS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script data-require="es6-shim#0.32.2" data-semver="0.32.2" src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.32.2/es6-shim.min.js"></script>
</head>
<body>
<div ng-app="app" ng-controller="SampleCtrl as sc">
<h3>Hello {{sc.firstName + " " + sc.lastName}}!</h3>
</div>
<script>
(function(){
'use strict';
class SampleCtrl {
constructor () {
this.firstName = "John";
this.lastName = "Doe";
console.log("ctrl works");
}
}
angular
.module('app')
.controller('SampleCtrl', SampleCtrl);
})();
</script>
</body>
</html>
I don't really know what I'm missing here but I keep getting the following errors in console:
Uncaught Error: [$injector:nomod] http://errors.angularjs.org/1.4.8/$injector/nomod?p0=app ...
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.4.8/$injector/modulerr?p0=app ...
My html output in browser:
Hello {{sc.firstName + " " + sc.lastName}}!
Update: Fixed module declaration as:
angular
.module('app', [])
.controller('SampleCtrl', SampleCtrl);
But now I'm getting the following error in console:
TypeError: Class constructor SampleCtrl cannot be invoked without 'new'

You're declaring the app incorrectly I believe:
angular
.module('app', [])
.controller('SampleCtrl', SampleCtrl);
Try that instead

use
angular.module('app',[]).controller('SampleCtrl', SampleCtrl);
If you are using to retrieve an existing module, You can use
angular.module('app').controller('SampleCtrl', SampleCtrl);
if you are creating a new module or overwrite any existing module, you use like this,
angular.module('app',[]).controller('SampleCtrl', SampleCtrl);

Problem finally fixed by using Angular JS version 1.6.x
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0-rc.2/angular.min.js"></script>

The answer BangularTK was already confirmed, but I'd like to offer an alternative for cases where people are not ready to update to a newer version of AngularJS for any reason.
I'm using 1.4.7 and I faced the exact same issue once I refactored a controller from a function into a ES6 class.
TypeError: Class constructor Classname cannot be invoked without 'new'
In order to work it around without updating AngularJS, I wrapped the construction of my class into a function.
In this example, it would like like:
<script>
(function(){
'use strict';
class SampleCtrl {
constructor () {
this.firstName = "John";
this.lastName = "Doe";
console.log("ctrl works");
}
}
function SampleCtrlWrapper() {
return new SampleCtrl();
}
angular
.module('app')
.controller('SampleCtrl', SampleCtrlWrapper);
})();
</script>
Again, not the best solution, but a temporary workaround to buy time before you update your AngularJS dependency.

Related

Integrate ts into html: uncaught ReferenceError clickbutton not defined

I try to build a simple CRUD frontend with no frameworks! I try to integrate a TypeScript file (intex.ts) into my index.html but it keeps beeing not found so that the called functions are undefined. I'm aware that browsers can't handle typescript but need javascript. I build my app before testing and all ts files get compiled. I tried integrating the compiled js file but it's not found either. All my frontend code is in directory src/public.
How do I connect my public/index.html with my public/index.ts so that the fundtions work?
relevant index.html code
<head>
<script type="text/typescript" src="index.ts"></script>
</head>
<body>
<button onclick="clickButton()">Click</button>
</body>
all index.ts code
function clickButton() {
document.getElementById("cases").innerText = "Hello Cases"
}
error i'm getting when clicking the button
index.html:18 Uncaught ReferenceError: clickButton is not defined
at HTMLButtonElement.onclick (index.html:18)
I use express in the backend and use express.static:
app.use(express.static("src/public"));
It seems to be an error caused because the function is defined outside of the global scope.
You can try to assign the function to the global window object just below of the function declaration:
function clickButton(){
...
}
window.clickButton = clickButton; // Now the function can be accessed from global scope
Also u can try to add the eventlistener on your JS file instead of using the html attribute onclick:
function clickButton(){
...
}
document.querySelector('.button-smth').addEventListener('click', clickButton);
This way you don't need to assign the function to the global scope at all, but you will need to add the class '.button-smth' (or whatever) to the html button element.
Hope this helps!
Your ts need to be compiled to js first. Then, you could possibly use it as follows -
function clickButton() {
document.getElementById("cases").innerText = "Hello Cases"
}
<head>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
<button onclick="clickButton()">Click</button>
<div id="cases"></div>
</body>
Note: This is just a possible solution

Error when trying to use plugins in redactor yii2

I'm trying to create a sample plugin and I'm getting this error:
Uncaught ReferenceError: RedactorPlugins is not defined
This is my code for plugin:
<?php
$script = <<< JS
(function($)
{
$.Redactor.prototype.advanced = function()
{
return {
init: function ()
{
var button = this.button.add('advanced', 'Advanced');
this.button.addCallback(button, this.advanced.test);
},
test: function(buttonName)
{
alert(buttonName);
}
};
};
})(jQuery);
JS;
$this->registerJs($script);
?>
My advanced plugin is load after redactor.js, what should i modify to make Redactor to accept plugins?
Thanks in advance!
If you looking your html code by your browser, I am sure that JS will be before the Redactor plugin and maybe before jquery too.
Just add the depends
$this->registerJs($script,['depends' => [\yii\web\JqueryAsset::className()]]);
then check the position of your code in your printed html
If it will be still before Redactor plugin, you can make a new JS file and add to AppAsset.php just below Redactor plugin

Programmatically loading a ES6 module with Traceur in web page

I have been using Traceur to develop some projects in ES6. In my HTML page, I include local Traceur sources:
<script src="traceur.js"></script>
<script src="bootstrap.js"></script>
and if I have a module in the HTML afterwards like:
<script type="module" src="foo.js"></script>
Then Traceur loads in that module, compiles it and everything works great.
I now want to programmatically add an ES6 module to the page from within another ES6 module (reasons are somewhat complicated). Here was my first attempt:
var module = document.createElement('script');
module.setAttribute('type', 'module');
module.textContent = `
console.log('Inside the module now!');
`;
document.body.appendChild(module);
Unfortunately this doesn't work as Traceur does not monitor the page for every script tag added, I guess.
How can I get Traceur to compile and execute the script? I guess I need to invoke something on either 'traceur' or '$traceurRuntime' but I haven't found a good online source of documentation for that.
You can load other modules using ES6 import statements or TraceurLoader API for dynamic dependencies.
Example from Traceur Documentation
function getLoader() {
var LoaderHooks = traceur.runtime.LoaderHooks;
var loaderHooks = new LoaderHooks(new traceur.util.ErrorReporter(), './');
return new traceur.runtime.TraceurLoader(loaderHooks);
}
getLoader().import('../src/traceur.js',
function(mod) {
console.log('DONE');
},
function(error) {
console.error(error);
}
);
Also, System.js loader seems to be supported as well
window.System = new traceur.runtime.BrowserTraceurLoader();
System.import('./Greeter.js');
Dynamic module loading is a (not-yet-standardized) feature of System:
System.import('./repl-module.js').catch(function(ex) {
console.error('Internal Error ', ex.stack || ex);
});
To make this work you need to npm test then include BrowserSystem
<script src="../bin/BrowserSystem.js"></script>
You might also like to look into https://github.com/systemjs/systemjs as it has great support for browser loading.
BTW the System object may eventually be standardize (perhaps under a different name) in the WHATWG: http://whatwg.github.io/loader/#system-loader-instance

Why can't I create my own custom component in Google Chrome 48?

I have built a library of custom elements using the webcomponents polyfills provided by Polymer. It works in Firefox and Safari. But it doesn't work in Chrome 48 with native component support. I can make it work if I use the polyfill code hacked to not use the native implementation...
Here is an example:
<!DOCTYPE html>
<html>
<head>
<script>
var myComp = Object.create(HTMLElement.prototype);
document.registerElement('my-comp', {prototype: myComp});
myComp.attachedCallback = function () {
console.log('my-comp attached');
}
</script>
</head>
<body>
<my-comp></my-comp>
<p> Just to check that page is loaded</p>
</body>
</html>
I should see the message in the console, but nothing is displayed. Support is enabled in Chrome (I can see that document.registerElement is native), my code is loaded and executed (the element is registered, I get a warning if I try to register it again in the console), and the callback is valid (I can call it by hand in the console).
What happens? How can I make it work?
You will make it work by attaching event handlers before registering element:
var myComp = Object.create(HTMLElement.prototype);
myComp.attachedCallback = function ()
{
console.log('my-comp attached');
}
document.registerElement('my-comp', {prototype: myComp});

How to configure my HTML to use i18next?

I have an application with nodejs, express and HTML on client side. I'd like to internalize my project using i18next. On nodejs side, it's ok, I required i18next and started it.
var i18n = require('i18next'),
app = express();
i18n.registerAppHelper(app);
i18n.init({lng: "en-US"}, function(t){
var trad = i18n.t("trad.key1");
console.log("trad = " + trad);
});
In console log, I have the traduction of translation.json to variable trad.key1. It is correct.
Know, the question: what I need to do to use i18next on client side, HTML page? I found some examples to do this, but using jQuery, and I don't use that.
Thanks for help.
It's done.
On HTML file, I needed to reference i18next.js and init i18n, like below. On init i18n, I specified the correct translation.json, as can you see.
<script type="text/javascript" src="i18next/i18next.js"></script>
<script>
window.onload = function() {
i18n.init({
lng: "en-US",
resGetPath:"locales/__lng__/translation.json"
},function(t) {
var translate = i18n.t("var.key1");
});
};
</script>
That's all.