Javascript Strategy Design Pattern issue - javascript

I am following this gist for a strategy design pattern.
https://gist.github.com/Integralist/5736427
I implemented this a few months ago and the chrome extension did not throw any errors when I implemented it but now its throwing a
"Uncaught TypeError: this.strategy is not a function"
var MessageHandling = function(strategy) {
this.strategy = strategy;
};
MessageHandling.prototype.greet = function() {
return this.strategy();
};
its strange because the functions that rely on this code still run but some other code that does not rely on it is limited.
Any ideas on how to fix it?

This is mainly about the object you create from MessageHandling, if you pass the right function while creating the object it should always work.
var MessageHandling = function(strategy) {
this.strategy = strategy;
};
MessageHandling.prototype.greet = function() {
return this.strategy();
};
var m = new MessageHandling(function(){console.log('hello');});
m.greet();
The above code will always work but if you instantiate the MessageHandling with passing a parameter which is not a function or not passing a parameter at all then it will complain that this.strategy is not a function. So you need to make sure you pass the right function to MessageHandling while creating its object.

You need to post your full code here in order for someone to figure out the problem. But from the exception text, it looks like you are passing an undefined strategy or a "variable that is not a function" to the constructor. The following sample will give the same "Uncaught TypeError: this.strategy is not a function exception:
// This is the Greeter constructor.
var Greeter = function(strategy) {
this.strategy = strategy;
};
// Greeter provides a greet function that is going to
// greet people using the Strategy passed to the constructor.
Greeter.prototype.greet = function() {
return this.strategy();
};
// Here are a couple of Strategies to use with our Greeter.
var politeGreetingStrategy = function() {
console.log("Hello.");
};
var friendlyGreetingStrategy = function() {
console.log("Hey!");
};
var boredGreetingStrategy = function() {
console.log("sup.");
};
var undefinedStrategy; //Not a function variable
// Let's use these strategies!
var politeGreeter = new Greeter(politeGreetingStrategy);
var friendlyGreeter = new Greeter(friendlyGreetingStrategy);
var boredGreeter = new Greeter(boredGreetingStrategy);
var wrongGreeter = new Greeter(undefinedStrategy); //No such strategy defined
politeGreeter.greet(); //=> Hello.
friendlyGreeter.greet(); //=> Hey!
boredGreeter.greet(); //=> sup.
wrongGreeter.greet(); //-> uncaught type

Related

JS: Add a function with "prototype" not possible

I really can't find the problem. The Browser always gives the following error:
TypeError: undefined is not a function (evaluating 'this._createButtons()')
This is my code:
function OpenSlider(el, steps) {
this.ul = el;
this.steps = steps;
this.slider_width = $(this.ul).width();
this.content_width = this.ul.scrollWidth;
this._createButtons();
}
OpenSlider.prototype = {
_createButtons : function() {
alert("created");
}
}
And in another document:
var slider = OpenSlider(document.getElementById("element-id"),1);
Maybe you could help me...
You need to new up the object with the OpenSlider constructor function:
var slider = new OpenSlider(document.getElementById("element-id"),1);
also change the line to:
OpenSlider.prototype._createButtons = function() {
alert("created");
};
as you are overwriting the prototype object instead of extending it with an additional function.

How to crossreference javascript class-properties?

In a project i experience problems with a javascript-scope. This is a basic question, but since im relatively new to js, it is hard to see the problem with this code.
The exception i got is: Uncaught TypeError: Cannot read property 'firstProperty' of undefined.
The jsfiddle
The code from the fiddle:
var someClass = function(){
var _someClass = {
firstProperty: 'hello world',
secondProperty: _someClass.firstProperty, // This line is not working like I expected it to work
}
return _someClass;
}
var someObject = new someClass();
If you want to reference firstProperty, then you can use something like this:
var someClass = function() {
var _someClass = new (function() {
this.firstProperty = 'hello world';
this.secondProperty = this.firstProperty;
})();
return _someClass;
}
var someObject = new someClass();
console.log(someObject.firstProperty);
console.log(someObject.secondProperty);
See it on JSFiddle.
This is because the _someClass.firstProperty is not yet defined. To make this work you should do something like this:
var someClass = function(){
var _someClass = {};
_someClass.firstProperty = 'hello world';
_someClass.secondProperty = _someClass.firstProperty;
return _someClass;
}
// The new here isn't actually necesary,
// since the object is created at the first
// line of the function. I actually don't
// know what happens here
var someObject = new someClass();
Also, to avoid future headaches, keep in mind that JS does not have classes. someClass is:
An object
A function
And since functions are objects and can have properties, you can use it as an object constructor but now I'm going off topic so I'll stop
This will help you look up more relevant information in the future

TypeError xxx is not a function

All, I am struggling with an error which says TypeError: curTemplete.addSection is not a function, Please forgive that I am not familiar with the js OO, Please help to review my problem. thanks.
The code looks like below.
Templete.js
LayoutTemplete=function(currentTmpContainer,templeteId,data)
{
var curTemplete = this;
curTemplete.addSection(null, null);//this line run with error above.
this.addSection = function(uiItem, data) {
alert('ddd');
};
};
In the dom ready event.
function loadTempleteContent(templeteId)
{
var jData=[{name: 'jerry'},{name: 'mike'},{name: 'claire'}];
var tmp = new LayoutTemplete($("#currentTmpContainer"),templeteId,jData);
}
You cannot call a function before it was defined. This has nothing to do with OOP. Consider this example:
foo();
var foo = function() {
alert(42);
};
It will throw a similar error.
Define the function/the property before you access it:
this.addSection = function(uiItem, data) {
alert('ddd');
};
this.addSection(null, null);
Better yet, define addSection on the prototype, so that you don't create a new function every time you create an instances of LayoutTemplete.
LayoutTemplete = function(currentTmpContainer,templeteId,data) {
this.addSection(null, null);
};
LayoutTemplete.prototype.addSection = function(uiItem, data) {
alert('ddd');
};
Felix is trying to tell you what your issue is, here it is explicitly:
var curTemplete = this;
curTemplete.addSection(null, null);//this line run with error above.
Here you reference and attempt to call curTemplete.addection, which has not been assigned a value yet, so it resolves to undefined. When the call is attempted, undefined is not a function (as the error tells you). addSection is not defined until the assignment below:
this.addSection = function(uiItem, data) {
alert('ddd');
};
Now it's defined. Move the assignment before the call (and if you're going to assign this to a local variable, you may as well use it):
var curTemplete = this;
curTemplete.addSection = function(uiItem, data) {
alert('ddd');
};
curTemplete.addSection(null, null);

YUI3 Objects and Namespacing with a Module

I'm having trouble understanding how to namespace and instantiate an object in YUI3. In the example below I'm creating a YUI3 module, loading it in the YUI.use method and trying to instantiate my object through namespacing. This doesn't work though, can someone point out why? I'm getting the error: "object is not a function" when trying to instantiate a new object.
test-module.js
YUI.add('test-module', function(Y){
var TestModule = {
url: '',
/* Example function */
doExample: function(){
console.log("doExample called");
}
}
// expose this back to the Y object
Y.namespace('SANDBOX.Test').TestModule = TestModule;
}, 1.0, {requires:['node']});
index.html
YUI({
modules:{
'test-module': {
fullpath: 'js/test-module.js',
requires: ['node']
}
}
}).use('test-module', function(Y){
var testModule = new Y.SANDBOX.Test.TestModule(); //this throws the error
testModule.doExample();
});
The problem in your code (where you say it throws an exception) is that you're using new () on a plain object. This is not a constructor function.
Change the line
var testModule = new Y.SANDBOX.Test.TestModule(); //this throws the error
for
var testModule = Y.SANDBOX.Test.TestModule; //this doesn't throw the error
As for instantiating objects, it's no different than normal Javascript:
var f = function(){
//This is the constructor
}
f.prototype.myfunction = function(){
//this is a function
}
You also can use their base object to create your own custom objects.
var x = Y.Base.create('ClassIdentifier', |Base object to extend from|, [Extensions], {
//content of the object, functions, etc
}, {
ATTRS: {
|attributes goes here|
}
};
Y.namespace('mynamespcae').X = x;
Then you can do:
var xInstance = new Y.mynamespace.X();
See http://yuilibrary.com/yui/docs/base/ or more specifically for create: http://yuilibrary.com/yui/docs/base/#create

Javascript inheritance misbehaviour

I have some js code here link deleted
If you open your js console and you'll run this code snipet
var r = new TempPopupForm("xxx");
r.create();
an error will appear
TypeError: this.init is not a function
this error is saying there is no init method implemented on this object.
But that's not true.As you can see in the code below the init method is declared.
TempPopupForm.prototype = new PopupForm();
TempPopupForm.prototype.constructor = TempPopupForm;
TempPopupForm.superclass = PopupForm.prototype;
function TempPopupForm(name) {
this.init(name);
}
TempPopupForm.prototype.init = function(name) {
TempPopupForm.superclass.init.call(this, name);
};
I guess something is wrong with the inheritance definition,but I can not figure out what it is.
BTW There are some third party dependencies.
EDIT
I was following this article and where the funcs are ordered like I have. The order actually works on the other classes, but not on this one.
http://www.kevlindev.com/tutorials/javascript/inheritance/inheritance10.htm
You need to re-order your functions and instantiation. Since your constructor is using one of its own prototyped method to init, they both need to be above the block where you instantiate the object. JavaScript hoists top-level functions.
Try this -
function TempPopupForm(name) {
this.init(name);
}
TempPopupForm.prototype = new PopupForm();
TempPopupForm.prototype.constructor = TempPopupForm;
TempPopupForm.superclass = PopupForm.prototype;
TempPopupForm.prototype.init = function(name) {
TempPopupForm.superclass.init.call(this, name);
};
var r = new TempPopupForm("xxx");
r.create();

Categories

Resources