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
Related
Assuming x is an external library and Thing is an object that can be constructed from x. This is all wrapped in an Angular service, like so:
app.service('thingService', function() {
var thing;
this.createThing = function(thingParam){
thing = new x.Thing(thingParam);
}
});
My initial attempt included this:
xSpy = jasmine.createSpyObj('x', ['Thing']);
spyOn(window, 'x').andReturn('xSpy');
But it still complains that x() method does not exist on that line that Thing should be constructed
Your attempt
xSpy = jasmine.createSpyObj('x', ['Thing']);
spyOn(window, 'x').andReturn('xSpy');
is wrong:
spyOn() replaces methods with spies, since x is an object this won't work. This is why you get the exception x() method does not exist.
Assuming your example you can just replace the attribute:
describe("Test", function() {
var origThing;
beforeEach(function() {
// create spy object for Thing that provides its methods
var mockedThingInterface = jasmine.createSpyObj('Thing', ['methodA', 'methodB']);
mockedThingInterface.methodA.and.returnValue(1);
mockedThingInterface.methodB.and.returnValue(2);
// remember original constructor
origThing = x.Thing;
// replace the constructor
x.Thing = function() {
return mockedThingInterface;
}
});
afterEach(function() {
// restore when finished
x.Thing = origThing;
});
it("should ...", function() {
// ...
});
});
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
I'm trying to create an Object containing other Objects and functions, in a prototype, the relevant part is the UI prototype;
var fChat = function() {
this.debug = true;
};
fChat.prototype = {
constructor: fChat,
Log: function(str){
if(this.debug){
console.log(str);
}
},
UI: {
Login: {
Show: function(){
this.Log("UI.Login.Show()");
}
}
}
};
var fChatInstance = new fChat();
fChatInstance.UI.Login.Show();
When i call fChatInstance.UI.Login.Show() It give me an error:
Uncaught TypeError: this.Log is not a function
Is that because by using this is on another scope?
Usually i do var self = this;at the start of a prototype, but i don't know how I can do that by using an Object prototype.
Yes. The problem is the javascript dynamic binding of this, to fix it you can set "this" to the object by using bind function. Change the fchat function refactor it like this:
var fChat = function() {
this.debug = true;
this.UI.Login.Show = this.UI.Login.Show.bind(this);
this.Log = this.Log.bind(this);
};
I have a javascript class called "LayoutProcessor".js ,defined as follow:
define('layoutProcessor', ['jquery'], function($) {
"use strict";
function LayoutProcessor() {
return (this);
}
LayoutProcessor.prototype.process = function() {
console.log('inside process');
};
LayoutProcessor.prototype.responseHandler = function() {
console.log('inside responseHandler');
};
return new LayoutProcessor();
});
I am trying to access the method "process" in another javascript class called "test.js", which is defined as follow:
test.js
require(['LayoutProcessor.js','jquery'], function(layoutProcessor,$) {
$(document).ready(function(){
var response = new LayoutProcessor().process();
});
})
But I am getting a type error:
new LayoutProcessor() is not a constructor.
As per the implementation by OP, it should be
var response = layoutProcessor.process();
not
var response = new LayoutProcessor().process();
Please refer the fiddle
The error message is appropriate, as its not a constructor but an object.
new LayoutProcessor() is not a constructor.
LayoutProcessor.js returns an Object.
return new LayoutProcessor();
There are few things going on with those code.
The way it is current written, LayoutProcessor module returns a constructed object, not a constructor to call.
To call it you would use:
var response = layoutProcessor.process();
However, this makes a singleton, which I doubt is what you mean.
In a singleton, there will only be one instance if layoutProcessor, since that instance is created by the LayoutProcessor module.
I believe the code that you mean would be more like this, where you create a new instance of the object for everyone that needs it:
layoutProcessor
define('layoutProcessor', ['jquery'],
function($) {
"use strict";
//----------------------------------------
/**
* constructor
*/
function LayoutProcessor() {
return (this);
}
LayoutProcessor.prototype.process = function() {
console.log('inside process');
};
LayoutProcessor.prototype.responseHandler = function() {
console.log('inside responseHandler');
};
// Note: Return a FUNCTION reference to be called later.
return LayoutProcessor;
}
);
test.js
require(['LayoutProcessor.js', 'jquery'],
function(LocalLayoutProcessor, $) {
$(document).ready(function() {
var response = new LocalLayoutProcessor().process();
});
}
)
Only issue is return statement. it should be
return LayoutProcessor;
I have this class definition:
$.note = function() {}
$.note.prototype = {
init: function(note) {
this.note = note;
this.ctrl = document.getElementById(note);
},
// I have these getter functions because I was getting errors using
// myObject.note or myObject.ctrl
getNote: function() {
return this.note;
},
getCtrl: function() {
return this.ctrl;
}
}
I created a new object with this class like this:
var note = new $.note('C');
Which I can access in my console like this:
But when I try and access note.getNote(), I get undefined as the response:
Am I going about accessing these properties incorrectly? I've tried using just note.note or note.ctrl, and I get the same thing...
Nothing's going to call that "init" function if you don't.
$.note = function(note) { this.init(note); }
Some frameworks provide an object system that uses constructor helper functions like that, but plain JavaScript doesn't.
Try this:
$.note = function(note) { this.note = note;}
or you should call init function:
var note = new $.note();
note.init('C');