I have a set of functions that manage CRUD operations on a database.
I am trying to have a top level function that houses the add, update, delete, etc. functions to keep it clean and organized.
I often see Javascript SDKs that look like users.add(param, param) where I am envisioning that it looks something like:
users = function(){
add = function(param,param) {
// do function
}
}
What is the proper way to to do this?
A simple way to do it would be to construct it as an object:
var users = {
add: function(param, param) {
//do function
},
edit: function(param, param) {
//do another function
}
//etc
};
users is usually an object literal, like so:
users = {
add:function(...) {...}
}
Alternatively, it could be an instanciated object (unlikely in this particular case):
function Users() {};
Users.prototype.add = function(...) {...};
users = new Users();
users.add(...);
You can do something like this:
var Users = {
add: function(a,b) {...},
remove: function(a) {...},
};
then call:
Users.add(a, b);
or:
var Users = function(options) { this.init(options); };
// Add a static method
Users.add = function(a,b) {...};
// Also add a prototype method
Users.prototype.remove = function(a) {...};
then do this:
var user = User.add(a, b);
or
var user = new User(user_id);
user.remove();
var users = {
add: function(params) {
// do stuff
},
// more functions
};
Maybe this could be helpful:
var User = function(name){
this.name = name;
this.address = "";
this.setAddress = function(address){
this.address = address;
}
this.toString = function(){
alert("Name: "+this.name+" | Address: "+this.address);
}
}
var a = new User("John");
a.setAddress("street abc");
a.toString();
and to manage a list of users:
var Users = function(){
this.users = new Array();
this.add = function(name, address){
var usr = new User(name);
usr.setAddress(address);
this.users.push(usr);
}
this.listUsers = function(){
for(var x = 0; x < this.users.length; x++){
this.users[x].toString();
}
}
}
var list = new Users();
list.add("Mickey", "disney Street");
list.add("Tom", "street");
list.listUsers();
working example: http://jsfiddle.net/N9b5c/
Related
i create 2 objects:
var Documentos = new QuadForm();
var Cadastro = new QuadForm();
And initialize this objects with lot of options
Cadastro.initForm(options);
Documentos.initForm(options2);
then i try to separate the data managed by each object with getName method but after the second object, myObjectName variable is overrided.
var QuadForm;
QuadForm = function () {
this.getName = function () {
// search through the global object for a name that resolves to this object
for (var name in window)
if (window[name] == this) {
window[name] = this;
window[window[name]] = window[name];
myObjectName= name;
break;
}
},
this.initForm = function (parms) {
this.getName()
$.extend(this, parms);
if (window.myState) {
delete window.myState;
}
this.containerId = parms.formId;
this.getForm(parms);
this.workflowLabels('hide');
then i use window[myObjectName].totalRecords but as it changes to the latest object name off course cannot access data.
How can i manage this.
It's not a big problem to manage several instances, but your approach is impossible, cause you can't really find all possible instances and your code does definitely not what you expected to do.
For example you can define a variable on the constructor-object which holds all instances, and than you can use it in some cases:
var QuadForm = function (name) {
this.name = name;
QuadForm.instances.push(this);
this.showAllOtherInstances = function () {
QuadForm.instances.forEach(function (instance) {
if (instance !== this) {
console.log('name: ' + instance.name);
}
}.bind(this));
}
}
QuadForm.instances = [];
var foo = new QuadForm('foo');
var anotherFoo = new QuadForm('foo');
var bar = new QuadForm('bar');
var aThirdFoo = new QuadForm('foo');
foo.showAllOtherInstances();
/*
* Output:
*
* name: foo
* name: bar
* name: foo
*/
I'm a JS beginner. I have defined a function on my Backbone model as follows.
myFunction: function () {
return {
firstAttr: this.model.get('value-attribute')
};
}
It is available to me as this.myFunction.
From somewhere else in the code, I want to extend this.myFunction to return another attribute. In other words, I'd like it to return a dict with two attributes: { firstAttr: 'something', secondAttr: true }.
How can I do this?
I've tried:
this.myFunction().secondAttr = true;
but I know that's the wrong thing to do.
Assuming your model prototype looks like
var MyModel = Backbone.Model.extend({
myFunction: function () {
return {
// I assume you work directly on a model
// the principle would be the same with a wrapper object
firstAttr: this.get('value-attribute')
};
}
});
you can either mask your method on a model by model basis like this:
var m = new MyModel({'value-attribute': 'attr, the first'});
console.log(m.myFunction());
m.myFunction = function () {
var res = MyModel.prototype.myFunction.call(this);
res.secondAttr = true;
return res;
};
console.log(m.myFunction());
See http://jsfiddle.net/V8zt2/ for a demo
Or dynamically modify your prototype to alter all instances :
var f = MyModel.prototype.myFunction;
MyModel.prototype.myFunction = function () {
var res = f.call(this);
res.secondAttr = true;
return res;
};
var m = new MyModel({'value-attribute': 'attr, the first'});
console.log(m.myFunction());
http://jsfiddle.net/V8zt2/1/
How about modifying your myFunction to :
myFunction : function () {
var i,
obj = {};
for (i=0; i< arguments.length;i++){
obj['attribute'+(i+1)] = this.model.get(arguments[i]);
}
return obj;
}
This way you can send keys of model, that you want to be in the returned object as arguments to myFunction.
I'm trying to create a nodejs module that will have an api like this
**program.js**
var module = require('module');
var products = module('car', 'pc'); // convert string arguments to methods
// now use them
products.car.find('BMW', function(err, results){
// results
})
products.pc.find('HP', function(err, results){
// results
})
>
**module.js**
function module(methods){
// convert string arguments into methods attach to this function
// and return
}
module.find = function(query){
// return results
};
module.exports = module;
I know this is possible because this module is doing the exact same thing.
I have tried to study the source but there is just to much going so was not able to determine how its doing this.
Something like this perhaps? Kinda hard to answer without additionnal details:
function Collection(type) {
this.type = type;
}
Collection.prototype = {
constructor: Collection,
find: function (item, callback) {
//code to find
}
};
function collectionFactory() {
var collections = {},
i = 0,
len = arguments.length,
type;
for (; i < len; i++) {
collections[type = arguments[i]] = new Collection(type);
}
return collections;
}
module.exports = collectionFactory;
Not sure what do you want to do but remember you can have dynamic property name of an object using [] notation like ...
var MyModule = function(param1, param2) {
this.funcTemplate = function() {
console.log('Hi ');
};
this[param1] = this.funcTemplate;
this[param2] = this.funcTemplate;
};
var dynamic = new myModule('what', 'ever');
I am trying to wrap my head around javascript modules, but I'm unsure how to split up a module into further sub modules. I have read that nested functions are not really a great idea, due to performance, so how do I break up a function in a module? For example, lets say I have the following module:
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
// This is where I need to define a couple smaller functions
// should I create a new module for bigFunction? If so, should it be nested in Editor.build somehow?
}
};
})();
bigFunction is only related to Editor.build. Should I attach the smaller functions that make up bigFunction to the prototype bigFunction object? I'm not even sure if that would make sense.
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
bigFunction.smallFunction();
bigFunction.prototype.smallFunction = function(){ /*do something */ };
// not sure if this even makes sense
}
};
})();
Can someone please throw me in the right direction here? There is so much misleading information online, and would just like a definite guide on how to deal with this sort of modularization.
Thank you.
Here is a snippet I use to make names for an input:
var dynamicCounter = 0;
//custom dropdown names
var createContainerNames = function () {
function Names() {
this.id = "Tasks_" + dynamicCounter + "__ContainerId";
this.name = "Tasks[" + dynamicCounter + "].ContainerId";
this.parent = "task" + dynamicCounter + "Container";
}
Names.prototype = { constructor: Names };
return function () { return new Names(); };
} ();
And then I use it:
var createdNames = createContainerNames();
var createdId = createdNames.id;
dynamicCounter++;
var differentNames = createContainerNames();
var differentId = differentNames.id;
Another approach would be to do this:
var NameModule = function(){
//"private" namemodule variables
var priv1 = "Hello";
//"private namemodule methods
function privMethod1(){
//TODO: implement
}
//"public namemodule variables
var pub1 = "Welcome";
//"public" namemodule methods
function PubMethod(){
//TODO: pub
}
return {
pub1 : pub1,
PubMethod: PubMethod
};
and then to use it
var myPubMethod = new NameModule();
myPubMethod.PubMethod();
var pubVar = myPubMethod.pub1;
EDIT
You could also take this approach:
var mod = function(){
this.modArray = [];
};
mod.prototype = {
//private variables
modId: null,
//public method
AddToArray: function (obj) {
this.modArray.push(obj);
}
}
See this code:
var MyObject = new function() {
this.tos = new Array();
this.show = function() {
this.clearTimeouts();
$("#divExample").slideDown(null,function() {
MyObject.tos[MyObject.tos.length] =
setTimeout(function(){MyObject.doSomething();} , 1800);
});
return;
};
this.doSomething = function() {
return;
};
this.clearTimeouts = function(){
for (var i=0; i<this.tos.length; i++)
clearTimeout(this.tos[i]);
this.tos = new Array();
return;
};
}
MyObject and it's methods are used in a few places. Maybe it's a bad way to do it, I dunno. I didn't want to tie it too closely with jQuery for my own reasons, so leaving it like this made sense as I can easily change the slide to style.display.
The problem is that I dont like referencing the object as MyObject in the callback of the jQuery slide, but I have to to add the timeout reference to my array of them so they can all be cleared. Is there a better way to do this?
Thanks!
You could try something like this:
this.show = function() {
var obj = this;
obj.clearTimeouts();
$("#divExample").slideDown(null,function() {
obj.tos[obj.tos.length] =
setTimeout(function(){obj.doSomething();} , 1800);
});
return;
};
var MyObject = (function() {
// private variable
tos = new Array();
// private method
function doSomething() {
// do something
// ..
}
// return an instance with public methods
return {
show: function() {
this.clearTimeouts();
$("#divExample").slideDown(null,function() {
tos[tos.length] =
setTimeout(function(){ doSomething(); } , 1800);
});
},
clearTimeouts: function() {
for (var i=0; i<tos.length; i++)
clearTimeout(tos[i]);
tos = new Array();
}
}
};