cant call function in another dojo module from dojo module - javascript

I'm having trouble calling a method from my dojo module in another dojo module. The code of my calling module is:
define([
"Templates/MarkTicket",
"DataTypes/MarkTicketForm_Data",
"DBCalls/MarkTicketDB",
...], function (MarkTicket, MarkTicketForm_Data, MarkTicketDB, ...
) {
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
postCreate: function () {
//both modules have Test Method
MarkTicketDB.Test("call from MarkTicketForm");//works great
MarkTicket.Test("call from MarkTicketForm");//object doesnt support property or method test
},
...
});
});
The call to Test in MarkTicketDB works just fine, but I get the error shown in the code comment when I try to call Test method in MarkTicket. MarkTicket only shows a Createsubclass and extend method when I debug. The module I'm calling these methods from is also located in the Templates directory -- could this be the problem? (I've also tried defining Templates/MarkTicket as just MarkTicket in the define statement)The Templates package is defined in my main page
Any ideas?
Thanks
As I said in my comment I think the problem may be that my calling module (MarkTicketForm) is a dijit dialog that is instantiated and opened through MarkTicket here is the code:
MarkTicket:
...
postCreate: function () {
MT = new MarkTicketForm();//instaniate MarkTicketForm inside MarkTicket
}
...
//call a Method in MarkTicket Form to open the dialog
MT.showForm(TicketInfo);
...
MarkTicketForm (code to show dialog):
...
showForm: function (ticketInfo) {
ID = ticketInfo.ID;
var DateRcvd = this.formatDate(ticketInfo.DateRcvd);
this.lblID.innerHTML = ticketInfo.ID;
this.lblTicket.innerHTML = ticketInfo.Ticket;
this.lblRcvd.innerHTML = DateRcvd;
this.lblType.innerHTML = ticketInfo.TicketType;
this.myDialog.show();
},
...

Like g00glen00b said, you should have listed the code for MarkTicket. However, since you said that:
MarkTicket only shows a Createsubclass and extend method when I debug.
...it's clear that MarkTicket is a class created through dojo.declare().
Presumably Test() is an method on MarkTicket instances, not on the MarkTicket class itself. Therefore, you could do something like this:
var m = new MarkTicket();
m.Test("call from MarkTicketForm");

Related

Vaadin 14 Springboot javascript does not work

I'm trying to develop my first Vaadin 14 application, I'm also using Spring boot framework for it.
I've created a javascript file, I put it into the folder frontend/src with the name of teams.js and I'm trying to import it with #JsModule("src/teams.js"). My root view class looks like this:
#Route("")
#PageTitle("Teams organization store init")
#Slf4j
#JsModule("src/teams.js")
#Tag("TeamsEntry")
public class TeamsEntryView extends VerticalLayout implements BeforeEnterObserver {
public TeamsEntryView() {
initTeams();
}
private void initTeams() {
var ui = UI.getCurrent();
var page = ui.getPage();
log.info("Teams initialization...");
page.executeJs(getTeamsConfig()).toCompletableFuture().whenComplete(((jsonValue, throwable) ->
log.info("Teams initialization completed: {} with throwable {}", jsonValue.toJson(), throwable.getMessage())
));
}
private String getTeamsConfig() {
return """
console.log('ss');
window.initTeams();
console.log('xx');
return true;
""";
}
...
My js file looks like this:
window = {
initTeams: function () {
console.log('initTeams...');
}
}
In this case, I see "ss" in the browser's console, but nothing more.
If I remove the window.initTeams(); line I get "ss" and "xx" as well.
If I declare a simple function in the js file and call it without the "window" class I get similar results.
If I use #Javascript or page.addJavascript("src/teams.js") I get this error when the page loads: "> unexpected character"
If I try to call join() or get() on the completable future the browser freeze.
If I use #Javascript("frontend://src/teams.js") I get some CORS error like if it is trying to download something from the "frontend" host.
I've tried to put the #JsModule on a component instead of my view.. it does not work.
I've tried to put my js file to the root, and to the resources folder.
I could not find any other solution to import and use my js file into vaadin14 with spring boot.
Also, I'm not sure why the browser freeze if I call "join()" on completable future, and also the on the result of it sentToBrowser returns false even if I see the console logs in the browsers log...
Can somebody explain to me how should I do the javascript import, why my current code does not work, and why the "join()" freezes the browser, please?
Thank you in advance!
#Edit
I have also tried with this annotation #JavaScript("./src/teams.js") and a js like this:
function initTeams () {
console.log('initTeams...');
console.log("Teams initialized!")
}
#Edit
Okay so finally I got it working.
The js file has to be under root/src/main/webapp/src folder.
Nor #JavaScript and nor the #JsModule worked for me, so I had to import my js file as:
var ui = UI.getCurrent();
var page = ui.getPage();
page.addJavaScript("src/teams.js");
Then I can call it like window.initTeams() or like initTeams() and both works fine. Altough the completable future below still never executes, and isSentToBrowser() always returns false.
page.executeJs(getTeamsConfig()).toCompletableFuture().whenComplete(((jsonValue, throwable) ->
log.info("Teams initialization completed: {} with throwable {}", jsonValue.toJson(), throwable.getMessage())
));
I must mention if I start the path with '.' like page.addJavaScript(".src/teams.js"); then it does not find the file.
Does anybody have an answer, why the completable future never executes?
The problem is that the following code redefines the window object:
window = {
initTeams: function () {
console.log('initTeams...');
}
}
Did you meant to add a function to the window object? Like so:
window.initTeams = function () {
console.log('initTeams...');
};
If you want to keep code visually similar to yours:
window = {
...window,
{
initTeams: function() {
console.log('initTeams...');
}
}
}
Other options:
window['initTeams'] = function() {...}
Object.assign(window, {initTeams: function() {...}})
Object.defineProperty(window, 'initTeams', {value: function() {console.log('foo')}});
Gotta love JavaScript...
Also, for more knowledge, the code mentioned in your #Edit section could not be called. Calling initTeams() is equivalent to window.initTeams(). The function must exist in the window object. This is why, for example, you see some custom elements defined like customElements.define(...) and window.customElements.define(...).

how to refactor anonymous function in npm using browserify

Learning npm with browserify.
I would like to refactor a code I wrote in modules.
For the sake of learning, I am trying to break it down little by little.
So far I have something like:
on index.html
<body onload=example.main()>
and on my javascript:
(var example = function() {
var helper = function (){
// smtg
}
// body:
// body is made by global objects, functions that I will then return on traps, e.g. main and helper. I would like now to separete functions and body in dedicated modules, to tide a bit the code
return {
main : function() {
// show main UX
},
helper : helper
}
})()
The first thing I want to do, is to export the function as a module, so that I can call example.main() on my index page.
I would like to start separate functions and "body", and then exports only traps I want in my example object.
I tried:
module.export = function () {
return example
}
var example = function() { ...} // no more calling the anonymous function
but got error example.main is not a function
and other attempts to export my example(), I cannot.
Is it maybe because it is not a constructor?
Could you help to show a syntax and logic of a first example to export only the traps I want from example ( main, helper) and how would you refactor helper, main, and "body" in three different npm modules ?

How is modifying _init() affecting parent()?

I'm trying to update a Gnome-shell extension. In it, I override the _init method of an object, which I'm doing like this:
function newInitAppSwitcherPopup() {
this.parent();
...
}
AltTab.AppSwitcherPopup.prototype._init = newInitAppSwitcherPopup;
The new method fails with:
JS ERROR: TypeError: The method 'parent' cannot be called
What I find very surprising here is that the parent method actually exists (if I change the name I get a "not defined" error).
What I don't understand is that the original AppSwitcherPopup._init is still using this call to parent (https://git.gnome.org/browse/gnome-shell/tree/js/ui/altTab.js?h=gnome-3-16#n54).
This was working well under Gnome 3.12, but is broken for Gnome 3.16...I guess they changed something in their GObject or inheritance models?
i have a similar code working for my config widget
const MenuConfigWidget = new GObject.Class({
Name: 'SimpleMenu.Prefs.MenuConfigWidget',
GTypeName: 'SimpleMenuMenuConfigWidget',
Extends: Gtk.Grid,
_init: function(params) {
this.parent({... });
...
}
});
Do you extend the class our just monkey patch the _init function?

Javascript Jasmine Testing: Prevent tested function to call function from object that was created within tested function

I want to test a Javascript function with Jasmine that has a structure like this:
showEditUser: function (...) {
// more code here...
var editUserView = new EditUserView();
// more code here...
editUserView.generate(...);
}
editUserView.generate() causes an error. That does not matter because I don't want to test it. But how can I prevent it from being called?
EditUserView is a RequireJS Module that extends another Module called BaseView. The function generate() is defined in BaseView. There are other Modules that extend BaseView and I want all of them not to call generate while testing. How can I do that with Jasmine? It seems not to be possible with spyOn(...).and.callFake() because I don't have the editUserView Object when calling the function. Is there kind of a static way to tell Jasmine to callFake() the function generate in BaseView?
There is no "nice" way to solve this with jasmine. I think, to take a BaseView viewObj as parameter is a nicer coding style. It will reduce the dependencies of the method. So it don't have to know the specific BaseView-class, he will simply need a viewObj that has a generate-method.
showEditUser: function(..., viewObj) {
// ...
viewObj.generate(...);
}
Then you could create a ViewMock and put it into that function like this:
var viewMock = {};
viewMock.generate = jasmine.createSpy('generate() spy');
Then you will call it this way:
showEditUser(..., viewMock);
EDIT: Here is a similar question

How to spy on a Marionette view that extends an external library with Jasmine

I have a view who extends an external library (let's call it ExtLib) also based on backbone marionette. Basically this lib is a wrapper of common views that share behaviours (e.g. DetailsView, FormView, etc..). So, let's say I have something like this:
MyApp.module('Views', function(Views, App, Backbone, Marionette, $, _) {
Views.MyDetailsView = Marionette.ExtLib.DetailsView.extend({
options: {
fields: [
// ...
],
myFunction: function() {
// ...
}
}
});
});
In my Jasmine test, I call a controller method that creates an instance of MyDetailsView.
it('does what it should', function() {
// ...
controller.showDetails();
// my expectations
});
Actually, the method in controller just creates the view and render it (into a layout's region).
showDetails: function(story) {
var container = new App.Layouts.DetailsLayout();
var myDetailsView = new App.Views.MyDetailsView({
model: story
});
container.details.show(storyDetailsView);
}
Finally, here's the error that i get:
TypeError: Cannot read property 'length' of undefined
at eval (eval at <anonymous> (http://localhost:8080/myapp/js/lib/underscore/underscore-min.js?_debugResources=y&n=1354890505115:30:350), <anonymous>:17:35)
at c (http://localhost:8080/myapp/js/lib/underscore/underscore-min.js?_debugResources=y&n=1354890505115:30:430)
at Object.Backbone.Marionette.Renderer.render (http://localhost:8080/myapp/js/backbone-app/conf/renderer.js?_debugResources=y&n=1354890505115:9:17)
at r.ItemView.r.View.extend.render (http://localhost:8080/myapp/js/lib/backbone/backbone.marionette.min.js?_debugResources=y&n=1354890505115:13:4719)
at Backbone.Marionette.ExtLib.ExtLib.DetailsView.Backbone.Marionette.View.extend.renderFieldView (http://localhost:8080/myapp/js/lib/backbone.marionette.extlib.min.js?_debugResources=y&n=1354890505115:395:14)
// etc...
I think that the problem is that jasmine is not aware of ExtLib. How can I spy on that renderFieldView to avoid the error?
Thanks in advance, as always.
I think that the problem is that jasmine is not aware of ExtLib.
I can't tell from that stack trace whether your diagnosis is correct; but to verify that, you can view source on the Jasmine runner and see if ExtLib is included in the runner's page.
If ExtLib is not included, then the fix depends on how you're running Jasmine. If you're using the Jasmine gem and you have a jasmine.yml file, you'll want to edit jasmine.yml to include ExtLib. If you have a "simple" configuration and you are maintaining Jasmine's included Javascript files by hand, then you'll need to add a line to include ExtLib in the runner's source file.

Categories

Resources