When is the Blockly.Workspace being created? - javascript

I am trying to override certain functions in the Blockly API. I am working with react and use the react-blockly package. I am overriding the workspace class. My code looks exactly like in the official repo and I changed the createVariable to look like this:
Blockly.Workspace.prototype.createVariable = function (
name,
opt_type,
opt_id,
opt_length
) {
return this.variableMap_.createVariable(name, opt_type, opt_id, opt_length);
};
As you can see the function is using the variableMap_ which is getting instantiated when calling Blockly.Workspace:
Blockly.Workspace = function (opt_options) {
...
this.variableMap_ = new Blockly.VariableMap(this);
...
}
When I run my code Blockly.Workspace is never called and variableMap_ is undefined.
When I search where Blockly.Workspace is used in the official repo I am not able to find out where it is getting called:
Workspace extends Workspace__Class and is only mentioned in the compressed file and the workspace.js file.
So my question: When is Blockly.Workspace called and this.variableMap_ instantiated?

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.

Why is a function provided by require undefined in a class instance? [duplicate]

This question already has an answer here:
Require returns an empty object
(1 answer)
Closed 1 year ago.
I'm asking this mostly as a sanity check, I'm unsure if I have made a mistake somewhere or if this fundamentally does not work.
I am converting some Java to Nodejs, A class called Site populates itself from a database via the dataFunctions.getSiteInfo(id) function. It also stores a list of Page instances.
The issue is that dataFunctions is returning as undefined when an instance of Site is created.
Have I misunderstood how classes and modules work in this case? Is it possible for instances of this class to access the dataFunctions module? Likewise is it possible for the Site class to reference the Page class as well? Or have I made some other silly mistake?
Site.js
let Page = require('./Page.js');
let dataFunctions = require('../DataFunctions.js');
module.exports = class Site {
constructor(id) {
this.id = id;
this.pages = [];
console.log(dataFunctions);
this.siteInfo = dataFunctions.getSiteInfo(id);
DataFunctions.js
let Site = require('./classes/Site.js');
function makeASite() {
let id = 2;
let site = new Site(id);
}
function getSiteInfo(id) {
etc etc
}
module.exports = {
getSiteInfo: function (id) {
return getSiteInfo(id);
},
};
Based on the code provided, I believe you forgot to create a new dataFunctions instance.
const df = new dataFunctions();
console.log(df);
If dataFunctions is providing static functions, make sure that the getSiteInfo method is static.
Otherwise, additional details may be needed.
Edit
It looked like the project structure and the require paths were wonky, but it's hard to tell.
When I run the code provided using the project structure inferred by the require statements, I'm not able to reproduce your issue.
However, one problem that I do see is that you're requiring the Site.js module from the DataFunctions.js module and requiring the DataFunctions.js module from the Site.js module, creating circular dependencies. Try eliminating these by moving makeASite to the Site.js module, for instance.

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;
});

Override functions in /_core/js/product.js

I need to customize the behavior of a function in product.js under /_core/js. The function declaration is:
function replaceAddToCartSections(data) {}
I tried by creating a function with the same name in custom.js. Since this one is the last js file loaded in the HTML, I thought the original function would be overriden, but that wasn't the result.
When I print replaceAddToCartSections.toString() in Mozilla dev tools, I get my new function. However, when I remove the function from custom.js, I get :
ReferenceError: replaceAddToCartSections is not defined
Are the functions of core.js private? How to override them? Is is something relative to Webpack configuration?
Just after replaceAddToCartSections is called, updatedProduct is emitted, so you can define a function like:
prestashop.on('updatedProduct', function (event) {
// your code
})

Accessing variable from different files(module) using requirejs

I am trying to make MVC structure of application in canjs. For that I am using requireJS to separate the code in different file.
I have searched in google and i am following this tutorial but in that tutorail I dont find to access module variables in different modules. therefore I am following this method to do so.
But I cannot achieve that.
This is my code:
requirejsconfig.js file :
requirejs.config({
paths :{
enforceDefine: true,
waitSeconds : 0,
jquery : "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min",
main : "view/main",
player : "view/player",
PlayerModel : "/models/PlayerModel",
hbs : "/models/view/js/handlebars",
fixture : "/models/view/js/can.fixture",
can : "/models/view/js/can.jquery"
}
});
main.js :
require(["player"],function(player){
player.PlayerModel();
});
I want to use that model methods in my controller.
player.js :
define(['PlayerModel'],function(){
function PlayerModel(){
var Player = PlayerModel.Player;
Players =can.Control({ defaults :{view:view/players.hbs' }},{
init: function(){
this.element.html(can.view(this.options.view, {
players: this.options.players
}));
}
$(document).ready(function(){
$.when(Player.findAll()).then(
function(playersResponse){
var players = playersResponse[0];
new Players('.players', {
players: players
});
});
});
}
});
PlayerModel.js:
define(function(){
var Player = can.Model({
findAll: 'GET /models/players.json',
findOne: 'GET /players.json/{id}'
});
return {
Player:Player
}
});
Every file is being loaded (saw in network tab-chrome devtools) but nothing is being populated in output.
Can anybody help me ?
Thanks in advance!
Carrying on with what #ekuusela said, restructure the code in Player.js in this format:
define(['PlayerModel'],function(){
function PlayerModel(){ ... }
return {
PlayerModel: PlayerModel
}
});
What's happening
Internally, two conventions are followed when defining modules. These relate to:
What the module is called (its label)
What this label represents.
Labeling Modules
The filename is taken as the module's name (unless shim is used, like you have). In other words, the define(['Module_Name'] ...), which is how I would normally read that line, can more accurately be read as a define(['Module_Path_Or_Shim_Symbol_Name' ...)
What Is This 'Module' Anyway
A module isn't magic - it is just a specially labeled map to a function. This map is maintained by RequireJS and probably looks similar to this:
var ModuleMap = {
'Player' : function (...) { ... },
'PlayerModel' : function (...) { ... }
};
Every time a module is accessed, through a require or define call, this map is accessed, and the relevant function found. However, that isn't enough - what we want is the stuff that is defined within the function - the fundamental concept of modules is that everything inside them has Module Function Scope, and is not exposed outside. So, to gain access to this "stuff", the RequireJS brain does the only thing it can do with a function - execute it.
var playerReference = require('Player');
Note that I've used the CommonJS notation of requiring modules, which is more readable for our current purpose.
So, in the code you posted, the module function has defined and declared PlayerModel as a function, but has not exposed it. Since the line player.PlayerModel() expects the module to return an object with a property named PlayerModel that refers to your function, the logical return value of the module is:
var exposedModuleReference = { PlayerModel: PlayerModel };
return exposedModuleReference;
Note that this means the name with which the function is exposed can be different from the function name itself. For example, the following code will also work without any changes anywhere else:
define(['PlayerModel'],function(){
function PlayerModelConstructor(){ ... }
return {
PlayerModel: PlayerModelConstructor
}
});
An Interesting Addition
So, executing a module function and assigning that return value to a reference is one part of what RequireJS's brain does. The other part is, it then updates this map so it now looks like this:
var ModuleMap = {
'Player' : { PlayerModel: PlayerModelConstructor },
'PlayerModel' : function (...) { ... }
};
This means that code written in module functions gets executed at most one time.
You define the function PlayerModel inside player.js and then require a module called PlayerModel there but don't assign the required module to any variable. You should first clean up your code, possibly rename some of your modules and move functions around.
Here, you try to access the function PlayerModel in the module player, but the module factory function in player.js doesn't return anything:
require(["player"],function(player){
player.PlayerModel();
});
What gets assigned to the function parameter player is only whatever you return from the function that defines the module. (If you would define a module as an object then that object would be the argument.)

Categories