angular equivalent to object prototype - javascript

Now i wish to create an object that you can instanciate at any time but that can still use angular services:
Take for instance the following object:
var myObject = function (variableOne, variableTwo) {
this.variableOne = variableOne;
this.variableTwo = variableTwo
};
myObject.prototype.useAngularService = function () {
return $sessionStorage.user;
};
Ofcourse this object cannot use $sessionStorage but my question is how would you create an object like that, that actually could utilize angular services?
The reason why i want to use this method instead of a service or a factory is basicly that i want different instances of this object and i am not looking for a singleton solution.

You could return your type from a factory. The factory would then have the Angular services and you would close around them.
yourModule.factory('yourName', function($sessionStorage) {
var myObject = function (variableOne, variableTwo) {
this.variableOne = variableOne;
this.variableTwo = variableTwo
};
myObject.prototype.useAngularService = function () {
return $sessionStorage.user;
};
return myObject;
});
You can also request any registered service with $injector.get(...) but that makes for brittle code.

You would inject $sessionStorage as a dependency into your object upon construction:
var myObject = function ($sessionStorage, variableOne, variableTwo) {
this.$sessionStorage = $sessionStorage;
this.variableOne = variableOne;
this.variableTwo = variableTwo
};
myObject.prototype.useAngularService = function () {
return this.$sessionStorage.user;
};
You would then create a service which acts as a factory for such objects:
function myObjectFactory($sessionStorage) {
this.$sessionStorage = $sessionStorage;
}
myObjectFactory.prototype.getInstance = function (variableOne, variableTwo) {
return new myObject(this.$sessionStorage, variableOne, variableTwo);
};
myModule.service('myObjectFactory', myObjectFactory);
You then include that factory as a dependency for your controller or other service:
myModule.controller('myController', function (myObjectFactory) {
var obj = myObjectFactory.getInstance(1, 2);
obj.useAngularService();
}

Related

return whole self invoking functions

How can I return the whole object of the self-inv-function without returning every functions manually?
I want to try with the following solution which should normally work, however, it does not work:
var publish = (function() {
var pub = {};
pub.hello = function() {
return "test"
};
return pub;
}());
now "pub" must be callable by subscribe:
var subsribe = (function(pub) {
function hello() {
return pub.hello();
};
}(publish));
I loaded both files in the browser (pub first).
However:
Debugger says: ReferenceError: pub not defined.
I think you want to write them like this:
var publish = (function() {
var pub = {};
pub.hello = function() {
return "test"
};
return pub;
})();
var subsribe = (function(pub) {
function hello() {
return pub.hello();
};
console.log(hello());
})(publish);
However, keeping a global reusable collections of functions can be accomplished in other ways, more elegantly maybe :) (separate file with export, singleton decorated with those methods)
You can't.
There's no mechanism in JS to get a list of variables in the current scope.
Even if you could, it probably wouldn't be a good idea as there would be no way to distinguish between public and private variables.
There is no such a mechanism but you can do something like this:
var publish = (function() {
const me = this;
let publicMethods = ['hello', 'bye'];
// private
function _hello() {
return "test";
};
function _bye() {
return "end test";
};
publicMethods.forEach((methodName) => {
let privateMethod = eval('_' + methodName);
Object.defineProperty(me, methodName, {
get: function() {
return privateMethod;
}
});
});
return this;
}());
console.log(publish.hello);
console.log(publish.bye);
console.log(publish.hello());
console.log(publish.bye());

Simple factory setter/getter in Angular?

I have this factory...
spa.factory("currentPageFactory", function() {
var pageDefinition = {};
pageDefinition.save = function(newPageDefinition) {
pageDefinition.value = newPageDefinition;
}
pageDefinition.read = function() {
return pageDefinition.value;
}
return pageDefinition;
});
...and this controller...
var pageDefinitionController = spa.controller("pageDefinitionController", ["currentPageFactory", function(currentPageFactory) {
currentPageFactory.save("foobar");
}]);
I have tested using the .read() function I created in this factory by including a definition in the factory of pageDefinition.value. I could read the variable using the getter just fine. The problem seems to lie in the setter.
I'm calling these functions like this...
/*Setter Call Example*/
currentPageFactory.save("blah");
/*Getter Call Example*/
this.foobar = currentPageFactory.read();
What am I doing wrong? Why is the setter not working?

JavaScript function prototype calling parent from child

I have a stupid reference problem
I declared a namespace variable called MYAPP
var MYAPP = MYAPP || function() {
this.name = 'My Application';
this.someImportantID = 123;
};
And then I wanted to sperate my code in namespaces/functions and so I did
MYAPP.prototype.homepage = function() {
urls: {
linkOne: '/link/to/some/page/',
linkTwo: '/link/to/some/page/'
},
doSomething: function() {
// ajax call
$getting = $.get(this.urls.linkOne)
// and so on .....
// how can I acces someImportantID ??
}
}
then i use it like this
app = new MYAPP();
app.homepage.doSomething();
but how can I access someImportantID within the function doSomething()
Get rid of this .homepage stuff. Why are you doing that anyway?
This is something of a constructor pattern. Declare your constructor:
var MYAPP = function(URLCollection) {
this._name = 'My Application';
this._someImportantID = 123;
this._URLCollection = URLCollection;
}
Then declare the instance methods:
MYAPP.prototype = {
doSomething: function() {
// ajax call
$getting = $.get(this._URLCollection.linkOne);
// and so on .....
// how can I acces someImportantID ??
}
}
Then declare your instance passing in your collection of links:
var lCollection = { linkOne: 'URL', linkTwo: 'URL' };
var myHomePage = new MYAPP(lCollection);
You can access doSomething from the instance:
myHomePage.doSomething();
You can get to some important ID from the instance also:
myHomePage._someImportantId;
Or from within the instance, by:
this._someImportantId;
This is rough - it should point you in the right direction.
If there are multiple MyApp instances then you can do the following:
//IIFE creating it's own scope, HomePage constructor
// is no longer globally available
;(function(){
var HomePage = function(urls,app){
this.urls=urls;
this.app=app;
}
HomePage.prototype.doSomething=function(){
console.log('urls:',this.urls,'app:',this.app);
}
//assuming window is the global
window.MyApp = function(urls){
this.name='app name';
this.homePage=new HomePage(urls,this);
}
}());
var app = new MyApp(['url one','url two']);
app.homePage.doSomething();
If you only have one app and that app only has one homePage object you can do it the following way as well:
var app = {
name:'app name'
,homePage:{
urls:['url one','url two']
,doSomething:function(){
console.log('urls:',this.urls,'app:',app);
//or
console.log('urls:',app.homePage.urls,'app:',app);
}
}
}
app.homePage.doSomething();
More on constructor functions, prototype and the value of this here.

JS turning a function into an object without using "return" in the function expression

i have seen in a framework (came across it once, and never again) where the developer defines a module like this:
core.module.define('module_name',function(){
//module tasks up here
this.init = function(){
//stuff done when module is initialized
}
});
since i never saw the framework again, i tried to build my own version of it and copying most of it's aspects - especially how the code looked like. i tried to do it, but i can't seem to call the module's init() because the callback is still a function and not an object. that's why i added return this
//my version
mycore.module.define('module_name',function(){
//module tasks up here
this.init = function(){
//stuff done when module is initialized
}
//i don't remember seeing this:
return this;
});
in mycore, i call the module this way (with the return this in the module definition):
var moduleDefinition = modules[moduleName].definition; //the callback
var module = moduleDefinition();
module.init();
how do i turn the callback function into an object but preserve the way it is defined (without the return this in the definition of the callback)?
you have to use:
var module = new moduleDefinition();
and then you're going to get an object.
Oh, and maybe you want to declare init as this:
this.init = function() {
Cheers.
How about something like this (I can only assume what mycore looks like):
mycore = {
module: {
definitions: {},
define: function(name, Module) {
this.definitions[name] = new Module();
this.definitions[name].init();
}
}
};
mycore.module.define('module_name', function () {
// module tasks up here
this.init = function () {
// init tasks here
console.log('init has been called');
};
});
I don't know what framework you're using or what requirements it places on you, but Javascript alone doesn't require a function to return anything, even a function that defines an object. For example:
function car(color) {
this.myColor = color;
this.getColor = function() {
return this.myColor;
}
//note: no return from this function
}
var redCar = new car('red');
var blueCar = new car('blue');
alert(redCar.getColor()); //alerts "red"
alert(blueCar.getColor()); //alerts "blue"
One more alternative http://jsfiddle.net/pWryb/
function module(core){this.core = core;}
function Core(){
this.module = new module(this);
}
Core.prototype.modules = {};
module.prototype.define = function(name, func){
this.core.modules[name] = new func();
this.core.modules[name].name = name;
this.core.modules[name].init();
// or
return this.core.modules[name];
}
var myCore = new Core();
var myModule = myCore.module.define('messageMaker', function(){
this.init = function(){
console.log("initializing " + this.name);
}
})
myModule.init();

Is it possible to append functions to a JS class that have access to the class's private variables?

I have an existing class I need to convert so I can append functions like my_class.prototype.my_funcs.afucntion = function(){ alert(private_var);} after the main object definition. What's the best/easiest method for converting an existing class to use this method? Currently I have a JavaScript object constructed like this:
var my_class = function (){
var private_var = '';
var private_int = 0
var private_var2 = '';
[...]
var private_func1 = function(id) {
return document.getElementById(id);
};
var private_func2 = function(id) {
alert(id);
};
return{
public_func1: function(){
},
my_funcs: {
do_this: function{
},
do_that: function(){
}
}
}
}();
Unfortunately, currently, I need to dynamically add functions and methods to this object with PHP based on user selected settings, there could be no functions added or 50. This is making adding features very complicated because to add a my_class.my_funcs.afunction(); function, I have to add a PHP call inside the JS file so it can access the private variables, and it just makes everything so messy.
I want to be able to use the prototype method so I can clean out all of the PHP calls inside the main JS file.
Try declaring your "Class" like this:
var MyClass = function () {
// Private variables and functions
var privateVar = '',
privateNum = 0,
privateVar2 = '',
privateFn = function (arg) {
return arg + privateNum;
};
// Public variables and functions
this.publicVar = '';
this.publicNum = 0;
this.publicVar2 = '';
this.publicFn = function () {
return 'foo';
};
this.publicObject = {
'property': 'value',
'fn': function () {
return 'bar';
}
};
};
You can augment this object by adding properties to its prototype (but they won't be accessible unless you create an instance of this class)
MyClass.prototype.aFunction = function (arg1, arg2) {
return arg1 + arg2 + this.publicNum;
// Has access to public members of the current instance
};
Helpful?
Edit: Make sure you create an instance of MyClass or nothing will work properly.
// Correct
var instance = new MyClass();
instance.publicFn(); //-> 'foo'
// Incorrect
MyClass.publicFn(); //-> TypeError
Okay, so the way you're constructing a class is different than what I usually do, but I was able to get the below working:
var my_class = function() {
var fn = function() {
this.do_this = function() { alert("do this"); }
this.do_that = function() { alert("do that"); }
}
return {
public_func1: function() { alert("public func1"); },
fn: fn,
my_funcs: new fn()
}
}
var instance = new my_class();
instance.fn.prototype.do_something_else = function() {
alert("doing something else");
}
instance.my_funcs.do_something_else();
As to what's happening [Edited]:
I changed your my_funcs object to a private method 'fn'
I passed a reference to it to a similar name 'fn' in the return object instance so that you can prototype it.
I made my_funcs an instance of the private member fn so that it will be able to execute all of the fn methods
Hope it helps, - Kevin
Maybe I'm missing what it is you're trying to do, but can't you just assign the prototype to the instance once you create it? So, first create your prototype object:
proto = function(){
var proto_func = function() {
return 'new proto func';
};
return {proto_func: proto_func};
}();
Then use it:
instance = new my_class();
instance.prototype = proto;
alert(instance.prototype.proto_func());

Categories

Resources