Override functions in /_core/js/product.js - javascript

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

Related

Javascript - pass THIS in function doesnt work

I am very new to Javascript and I just stuck with something that works in python.
The problem is that I have class where I initiate some empty lists as this.data_y_json and etc. If I make normal function inside class like normal_function(){this.data_y_json = 5} it works and the variable is changed.
However, i work with d3, and there is some trick which I cant get through:
// inside class
// in constructor all this.xxx defined
// after object initiation I call set_data()
set_data(){
d3.json("link2.json",function(data) {
for (var i=0;i<data.d.results.length;i++){
this.data_y_json.push(parseFloat(data.d.results[i].PE))
...
//end of function
// end of class
After calling function set_data() an error is raised: SCRIPT5007: Unable to get property 'data_y_json' of undefined or null reference
I am rewriting my visualization into OOP, before this, I had it solved with global variables and it worked fined. In python I would just passed 'self' as an argument to function, but here in javascript, passing THIS doesnt work and raises another error.
Simply said, I know the problem -> this.data_y_json is not recognized propably because of function(data) doesnt pass self of the object, but I dont know how to do it.
Thank in advance for advice
Are you in an ES2015 environment? Changing your callback to be an arrow function should scope this to be what you want
d3.json("link2.json", (data) => {
for (var i=0;i<data.d.results.length;i++){
this.data_y_json.push(parseFloat(data.d.results[i].PE))
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
For reading up on the arrow function and the scoping of this

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.)

rails 3 javascript fine coffeescript referenceerror (class) is not defined

Someone on the RubyRogues podcast once said "Learn CoffeeScript because CoffeeScript writes better javascript than you do." Sorry, can't remember who said it...
So, I took a very simple WORKING javascript function:
togglingii.js
function pdtogglejs(id) { $('div .partybackground').removeClass("hidden"); }
Which is being called by this line:
Read More...
Then I converted it into this coffeescript:
toggling.js.coffee
pdtogglecs(id) ->
jQuery('div .partybackground').removeClass("hidden")
and changed the html to reference the pdtoggle*c*s instead of pdtoggle*j*s.
I can see BOTH of them just fine in my application.js file:
(function() {
pdtogglecs(id)(function() {
return jQuery('div .partybackground').removeClass("hidden");
});
}).call(this);
function pdtogglejs(id) { $('div .partybackground').removeClass("hidden"); }
;
(function() {
}).call(this);
However, only the pure javascript works. The coffeescript always returns Uncaught ReferenceError: pdtogglecs is not defined.
Based on other stackoverflow questions it must be some sort of namespace error. Probably because of the way pdtogglecs is, itself, inside of a function?? However, I have tried defining the coffeescript function with: window.pdtogglecs, this.pdtogglecs, root.pdtogglecs and the coffescript one always fails with that error.
What am I missing??
Thanks!!
You have two problems, one is a bit of CoffeeScript syntax confusion and the other is the namespace problem that you know about.
We'll start by sorting out your syntax confusion. This:
f(x) -> ...
is interpreted like this:
f(x)(-> ...)
So when given this:
pdtogglecs(id) ->
jQuery('div .partybackground').removeClass("hidden")
CoffeeScript thinks you're trying to call pdtogglecs as a function with id as an argument. Then it thinks that pdtogglecs(id) returns a function and you want to call that function with your -> jQuery(...) function as an argument. So it ends up sort of like this:
callback = -> jQuery(...)
returned_function = pdtogglecs(id)
returned_function(callback)
And that's nothing like your original JavaScript. You want to create a function named pdtogglecs which takes id as an argument and then runs your jQuery stuff:
pdtogglecs = (id) ->
# -----^ this is sort of important
jQuery('div .partybackground').removeClass("hidden")
You can see what's going on by looking at the generated JavaScript.
The namespace problem is easy and you can probably figure that out based on the other question you found. However, I'll take care of it right here for completeness.
CoffeeScript wraps each .coffee file in a self-executing function to avoid polluting the global namespace:
(function() {
// JavaScript version of your CoffeeScript goes here...
})();
That wrapper makes everything scoped to the .coffee file. If you want to pollute the global namespace then you have to say so:
window.pdtogglecs = (id) -> ...
You can also say:
#pdtogglecs = (id) -> ...
but I prefer the explicitness of directly referencing window, that also saves you from worrying about what # (AKA this) is when you're code is parsed.

jasmine: using function with a dot in the name

I'm testing a js function that uses functions from other js files.
One of my external js files has a function defined as such:
functionname.functionextension = function () {.....}
when testing using jasmine, and calling functionname.functionextension, it complains that functionname is not defined. I think it believes that functionname is an object..
I know that one way to get around this is to modify the function name but I can't do that. Is there any other way?
Thanks
In javascript, all functions are objects. In the external js file, the function is probably defined like this:
var functionname = functionname || {};
functionname.functionextension = function () {
...
};
If you're getting a script error that functionname is not defined, there is either an error in the external javascript or you are not calling some initialization function that the external script requires to set up its objects.
It worked for me...u need to call function by its full name like functionname.functionextension() while calling.

Override/Rewrite a javascript library function

I am using an open source javascript library timeline.verite.co
It's a timeline library which works great on page load. But when I try to repaint the timeline on certain condition, it starts giving out weird errors
I would like to modify the init function in the library. But instead of changing it in the original library itself, I would like to rewrite/override this function in another separate .js file so that when this function is called, instead of going to the original function, it must use my modified function.
I'm not sure whether to use prototype/ inheritance and how to use it to solve this problem?
You only need to assign the new value for it. Here is an example:
obj = {
myFunction : function() {
alert('originalValue');
}
}
obj.myFunction();
obj.myFunction = function() {
alert('newValue');
}
obj.myFunction();

Categories