Using TypeScript With jQuery Without AMD? - javascript

Is it possible to use TypeScript and jQuery (or any other non-Node JavaScript library) without AMD?
Currently my code compiles fine, but the compiled code cannot see the jQuery's $ function.
Given this TypeScript code:
/// <reference path="typings/tsd.d.ts" />
import $ = require('jquery');
export class Widget {
foo() {
$(selector).bar()
}
}
I'd like the following JavaScript:
var Widget = (function ($) {
function Widget() { }
Widget.prototype.foo = function () { ... };
return Widget;
})(jQuery);
Currently my code does not have jQuery passed to the anonymous function.
UPDATE 1
Per #basarat
Do it by hand. If its valid JavaScript then its valid TypeScript
You're suggesting (and I was thinking) that I do this:
var Widget = (function($) {
class Widget {
foo() {
$('body').append('foo');
}
}
return Widget;
})(jQuery);
?
That's not valid TypeScript and without that, I'm left with prototypes.
UPDATE 2
Per #basarat the above is supported with TypeScript 1.6.

Given this TypeScript code , I'd like the following JavaScript
This is not how the TypeScript js emit is designed to work.
So in short : no. You can't get this javascript from that typescript.
I know I can do this by hand. I want to know if there's a TypeScript way to do this.
Do it by hand. If its valid JavaScript then its valid TypeScript. There isn't a specific TypeScript way to do this thing. The JavaScript way is the TypeScript way in this case.
Update
That's not valid TypeScript and without that, I'm left with prototypes.
It is valid TypeScript starting with TypeScript 1.6.

Related

Blazor Webassembly multiple exports in single JS file returns error when minimized

I am trying to add get and set blazor culture as advised in the Microsoft Documentation.
According to the documentation, i can put the get and set Blazorculture in a single JS with 2 exports like below
The preceding example pollutes the client with global methods. For a better approach in production apps, see JavaScript isolation in
JavaScript modules.
Example:
JavaScript
export function getBlazorCulture() {
return window.localStorage['BlazorCulture'];
};
export function setBlazorCulture(value) {
window.localStorage['BlazorCulture'] = value;
};
If you use the preceding functions, change the JS interop calls in this section from blazorCulture.get to getBlazorCulture and from
blazorCulture.set to setBlazorCulture.
So i created a single Js file as below, i have tried using export on both function and as well as like using exports as below but error didnt go away.
export function getBlazorCulture() {
return window.localStorage['BlazorCulture'];
};
export function setBlazorCulture(value) {
window.localStorage['BlazorCulture'] = value;
};
function getBlazorCulture() {
return window.localStorage['BlazorCulture'];
};
function setBlazorCulture(value) {
window.localStorage['BlazorCulture'] = value;
};
exports {getBlazorCulture,setBlazorCulture}
that seems to be working fine but once I minimize this min.js, I am getting error message as
minimized js looks like
"use strict";function getBlazorCulture(){return window.localStorage.BlazorCulture}function setBlazorCulture(n){window.localStorage.BlazorCulture=n}Object.defineProperty(exports,"__esModule",{value:!0});exports.getBlazorCulture=getBlazorCulture;exports.setBlazorCulture=setBlazorCulture;
using on separate Js files, no error.

Odoo Override Javascript Class Method

First off, my apologies - I'm a complete novice when it comes to javascript so this is a bit above my head. I'm also fairly new to Odoo and have mostly stuck with python and XML customization thus far.
I'm trying to override a javascript method within a class to replace it completely with my own version. From the Odoo documentation (https://www.odoo.com/documentation/14.0/reference/javascript_reference.html#patching-an-existing-class) this should be a simple matter of using the .include() method to patch the original class with my new method. But when I do this I get an error Error while loading mymodule.CustomControlPanelModelExtension: TypeError: ControlPanelModelExtension.include is not a function
The original Odoo code that I'm trying to override:
odoo.define("web/static/src/js/control_panel/control_panel_model_extension.js", function (require) {
"use strict";
// a bunch of code here ...
class ControlPanelModelExtension extends ActionModel.Extension {
// more code here ...
// this is the method I'm trying to override
_getAutoCompletionFilterDomain(filter, filterQueryElements) {
// original method body here
}
// more code
}
// more code
});
Below is what I came up with based on the documentation but this gives me the error Error while loading mymodule.CustomControlPanelModelExtension: TypeError: ControlPanelModelExtension.include is not a function (this error is reported in browser dev tools console).
odoo.define('mymodule.CustomControlPanelModelExtension', function(require) {
"use strict";
var ControlPanelModelExtension = require('web/static/src/js/control_panel/control_panel_model_extension.js');
ControlPanelModelExtension.include({
// override _getAutoCompletionFilterDomain
_getAutoCompletionFilterDomain: function(filter, filterQueryElements) {
// my custom implementation here
},
});
});
Any ideas what I'm doing wrong here? I've tried various other things with extends and such but I don't think I want to extend - that won't replace the function in existing instances.
The problem here is that the include function is available only for the classes that inherit from OdooClass and in this case the class you are trying to inherit is a native JavaScript class.
Then, to add a property or method to a class, the prototype property of the object class must be modified.
odoo.define('mymodule.CustomControlPanelModelExtension', function(require) {
"use strict";
const ControlPanelModelExtension = require('web/static/src/js/control_panel/control_panel_model_extension.js');
function _getAutoCompletionFilterDomain(filter, filterQueryElements) {
// your custom implementation here
}
ControlPanelModelExtension.prototype._getAutoCompletionFilterDomain = _getAutoCompletionFilterDomain;
return ControlPanelModelExtension;
});

Calling javaScript function by a JavaScript class

I am a newbie in the ASP.NET technology and also I did not find any answer on the forum (however if there is one please let me know)
I am writing ASP.NET MVC app and I use a lot of Ajax there.
At the moment I am rewriting "free" Javascript into classes and their methods, so the code will be more readable.
And here is the problem:
For such a case:
#Ajax.ActionLink("Text", "SomeAction", "Controller", new AjaxOptions() { UpdateTargetId="content", HttpMethod="Post", OnComplete="javascriptActionStatedBelow"})
<script>
function javascriptActionStatedBelow()
{
// do stuff here
}
</script>
Everyting works perfectly fine. However when I try to input the function into the class and then call it, it does not work.
I am doing this in the following way:
<script>
// is in seperate file and here is added reference to it
class myClass {
javascriptActionStatedBelow() {
// do stuff here
}
}
// this is on the view page
var someObj = new myClass();
</script>
I initilize the object in the header and then in the body I put the following.
#Ajax.ActionLink("Text", "SomeAction", "Controller", new AjaxOptions() { UpdateTargetId="content", HttpMethod="Post", OnComplete= "someObj.javascriptActionStatedBelow" })
The second idea does not work.
What am I doing wrong ? Is there a better solution for managing javascript content in ASP.NET MVC applications while using AJAX ?
I know about $.ajax type of solution but actions like OnComplete, OnBegin,.. etc worked perfectly for now.
It's important to note that there are no classes in JavaScript. Functions can be used to somewhat simulate classes, but in general JavaScript is a class-less language. However from ECMAScript 2015, classes are introduced which are primarily syntactical sugar over JavaScript's existing prototype-based inheritance. For your requirement, should defined the java script function as IIFE. If your javascript is not targeted for ECMAScript 2015, then you can write the code as follows for IIFE:
Define the IIFE method as
var myClass = (function () {
// Object that's returned from the IIFE.
return {
javascriptActionStatedBelow: function() {
}
};
}());
Now in view's script section you can use it as
// this is on the view page
var someObj = myClass.javascriptActionStatedBelow();
Javascript isn’t strictly a “class-based” object-oriented language, hence the same patterns that apply to conventional back-end object-oriented languages don’t apply there effectively. However, there is a number of ways to make javascript much more convenient and manageable.
One of the ways that I highly recommend is through the use of “Module / Revealing module pattern”, or simply put through making javascript “namespaces” and calling them wherever needed. This reduces the clutter in View files and mimics the design we are used to seeing.
In a separate js file (conventionally named similar to the view file), you will define your javascript as follows:
var className = (function() {
// private variables and functions
var javacriptField1 = "some field";
var javascriptFunction1 = function() {
//function logic
}
var javascriptFunction2 = function() {
//function logic
}
// public API
return {
javascriptField1 : javascriptField1,
javascriptFunction1: javascriptFunction1,
javascriptFunction2: javascriptFunction2
};
})();
In your view you would include your js file:
<script src="~/Scripts/myfile.js"></script>
And use it within the javascript on your view as follows:
var obj = className.javascriptFunction1();
Following is a very nice tutorial you should go through:
https://www.dcaric.com/blog/asp-net-mvc-and-revealing-module-pattern
Here’s another example:
How to use javascript namespaces correctly in a View / PartialView

Building a Javascript utility library with AMD compatibility

My goal is to build a set of javascript tools for functional programming, to be used by our company's web developers. I've tried giving a look at the Underscore annotated source but I'm new with RequireJS and AMD, so it's a lot confusing for me.
To start I just want to have a variable that gets available when my library is imported.
In this case booleans is a module that has functions returning boolean values. For example: _myLib.booleans.isDefined(var) - returns true is var is a defined variable.
No I have RequireJS setup, but how do I make a variable available for usage?
My main.js:
requirejs(['app/booleans'], function (booleans) {
var _myLib = {};
_myLib.booleans = booleans;
return _myLib;
});
Of course _myLib is undefined, I suppose it's because it is not assigned to any scope.
Can anyone give me some lights on building this library?
Thanks in advance.
If you want to produce a proper AMD library, you need to set it so that it calls define to define itself as an AMD module.
define(['app/booleans'], function (booleans) {
var _myLib = {};
_myLib.booleans = booleans;
return _myLib;
});
If you called your file myLib.js and provided a good configuration to RequireJS for it to find it, then, when you want to use it, you can do:
require(["myLib"], function (myLib) {
myLib.booleans.isDefined("moo");
});
Or in another module:
define(["myLib"], function (myLib) {
myLib.booleans.isDefined("blah");
});

How to use multi-function modules with requireJS

I'm a Java programmer who's trying to convert some Applets into JavaScript. I have a case with lots of small Java classes, which have a cohesive design that I'd like to keep if possible in JavaScript. RequireJS seems like a great way to keep it modular.
However, all the tutorials for requireJS I've seen treat a module as only having a single function, which only works for a couple of my Java classes. For example, this tutorial defines the module purchase.js as having a single function purchaseProduct():
define(["credits","products"], function(credits,products) {
console.log("Function : purchaseProduct");
return {
purchaseProduct: function() {
var credit = credits.getCredits();
if(credit > 0){
products.reserveProduct();
return true;
}
return false;
}
}
});
Is there a way to allow more than one function per module in this way? In my head, a module is not necessarily just one function.
Or is RequireJS the wrong tree to be barking up for preserving my modular design from Java?
Edit
I found a much more useful set of examples for transitioning from Java to JS with requireJS at https://gist.github.com/jonnyreeves/2474026 and https://github.com/volojs/create-template
Yes, there's a way and it's very simple.
See, what you're returning (the module) is simply an object. In your code, this object has 1 property (purchaseProduct), but it can have as many as you'd like. And they don't all have to be functions either:
return {
purchaseProduct: function () {/*...*/},
returnProduct: function () {/*...*/},
discountLevel: 0.25
};
Just add more functions to the object you return:
return {
purchaseProduct: function() {
// ...
},
somethingElse: function () {
// ...
}
}
If you return this as the value of your module, you'll have a module that exports two functions purchaseProduct and somethingElse.

Categories