How to mangage javascript files and encapsulate JavaScript/jQuery functions - javascript

I need to write & manage a lot of JavaScript code for current project.
I separate them into multiple .js files mainly based on module.
So, now i have for example:
Map.js // deal with google map issue
Common.js // common functions that will share by all modules
User.js // user module js code
Geofence.js // geofence module js code
etc.....
For example, inside my User.js file
what if i want to declare a function that only used inside the User.js file, not accessible by outside. what can i do?
var User = {};
User.registerModule = function () {
$('#user').click(function () {
Common.showLeftScrollbar();
getAllUsers();
// ...
});
}
function getAllUsers(){ // how to hide this function
// get
return users;
}
So, in my home page, i only need to coordinate with multiple .js files. Access what allows to access.
$(document).ready(function (data) {
GoogleMap.initialiseGoogleMap();
Common.refreshRightScrollbar();
User.registerModule();
// ...
});
It is my first time to write js and not enough time to study a whole book. So, please, in your opinion, is this structure ok with many js code? and how to hide functions that i dont want outside to access?

to hide that function you have different possibilities
just enclose your code in an immediate self-executed anonymous function
var User = {}; // this should not be enclosed too
(function() {
User.registerModule = function () {
$('#user').click(function () {
Common.showLeftScrollbar();
getAllUsers();
// ...
});
}
function getAllUsers(){ // how to hide this function
// get
return users;
}
})();
enclose that function inside User.registerModule function
User.registerModule = function () {
function getAllUsers() { ... }
$('#user').click(function () {
Common.showLeftScrollbar();
getAllUsers();
// ...
});
}

Place this function inside the scope:
User.registerModule = function () {
function getAllUsers(){ // how to hide this function
// get
return users;
}
$('#user').click(function () {
Common.showLeftScrollbar();
getAllUsers(); // returns users
// ...
});
}
And it will be private.
Now if you try to call this function outside it will be undefined:
getAllUsers(); // undefined.

Related

Accessing an Immediately Invoked Function Expression variable in Node.js in another file using require

File 1 - Monitor.js
var MONITOR = (function () {
// File Content
return {
doThing: function() {
doThing();
}
};
})();
File 2 - Test.js
var monitor = require('../public/js/monitor.js');
I want to access doThing() in File 2. I have tried various syntax and no luck so far.
From the frontend HTML I can simply include Monitor.js in a script tag, and call MONITOR.doThing(); without trouble but in Test.js this is proving difficult.
Any advice on how?
You have to export MONITOR so that someone else can access it with require().
Add this:
module.exports = MONITOR;
at the bottom of Monitor.js.
And, if you want the monitor.doThing() method to return some value, then you have to add a return statement to the function as in:
var MONITOR = (function () {
// File Content
return {
doThing: function() {
return "hello";
}
};
})();

How to check duplicated function name in jQuery.fn.extend on webpack building

extendFunctions1.js
function func1Duplicated() { }
function func2() { }
function func3() { }
// ...
// ...
extendFunctions2.js
function func4() { }
function func5() { }
function func1Duplicated() { }
// ...
// ...
I want to add a task, that extends custom functions to jquery.fn.extend(), on webpack build.
How can I check the duplicated function name on making the bundle.js file.
like the 'function1Duplicated'
There is no way in javascript to find duplicated functions name
your func1Duplicated method is going to redefined and the last one gonna be call whenever you call func1Duplicated
you can check this link for more information

How to call a function from a chain of module.exports in node

I've declared a function in one of my models (review) and exported it in the standard node way so other files can use it. I then reference it another model (company) and export it there as well.
Finally, I'm trying to use the function defined in company in another file (companiesRoute) but I'm getting a company.getAllCompaniesWithReviews is not a function error.
Is what I'm trying to do even possible?
// review.js
module.exports.getAllCompaniesWithReviews = function(next) {
// ...
// ...
// ...
};
// company.js
var reviews = require('./review');
module.exports.getAllCompaniesWithReviews = reviews.getAllCompaniesWithReviews;
// companiesRoute.js
var company = require('../models/company');
company.getAllCompaniesWithReviews(function(err, result) {
// ...
// ...
// ...
});
If I try and call the function directly from companiesRoute then it works:
review.getAllCompaniesWithReviews(function(err, result) {
// ...
// ...
// ...
});
This is, of course, the answer. But why doesn't my version work?
Also, node v4.4.4.
Can you please try this in company.js?
module.exports.getAllCompaniesWithReviews = function(next) {
reviews.getAllCompaniesWithReviews(next);
}

Calling events in modular JavaScript

I'm only learning how to work with the modules in JavaScript, so I have three separate .js files: main, listener and fileHandler
Simply this is a program that for every selected or dropped file(image) from computer gets appended to the page. Functions are working when I drag and drop files to the page, but when I select them through inputBox button files even files are stored in inputBox.files, they are not getting appended to the page.
var uploader = {};
uploader.init = function () {
this.inputBox = document.getElementById('uploadButton');
this.dropbox = document.getElementById('dropbox');
this.listener();
}
and listener method as:
probably I'm calling 'change' event wrongly here, that files are not appended.
uploader.listener = function () {
uploader.inputBox.addEventListener('change', uploader.fileHandler.addFiles(uploader.inputBox.files));
this.dropbox.addEventListener('drop', this.fileHandler.drop.bind(this));
}
one another constructor is:
uploader.fileHandler = new function () {
var uploadHandler = function () {...}
this.addFiles = function (files) {
Object.keys(files).forEach(function (key) {
var file = files[key];
uploadHandler(files[key]);
});
};
this.drop = function (event) {
event.stopPropagation();
event.preventDefault();
var files = event.dataTransfer.files;
this.fileHandler.addFiles(files);
};
}
EDIT
I see another issue. When you do this:
uploader.inputBox.addEventListener('change', uploader.fileHandler.addFiles(uploader.inputBox.files));
You are calling uploader.fileHandler.addFiles(uploader.inputBox.files) immediately and passing it's return value to .addEventListener(). Probably what you want instead is this:
uploader.inputBox.addEventListener('change', function() {
uploader.fileHandler.addFiles(uploader.inputBox.files)
});
Here you are passing an anonymous function reference which can be called later by the event handler.
This construct:
uploader.fileHandler = new function () {
this.addFiles = function (files) {
Object.keys(files).forEach(function (key) {
var file = files[key];
uploadHandler(files[key]);
});
};
}
only assigns a function to uploader.fileHandler. It does not define uploader.fileHandler.addFiles until you actually call that function (which you do not show).
I don't know why you're trying to nest your function definitions (that usually just causes more complexity than benefit in Javascript), but if you really wanted to define them that way, you could do this:
uploader.fileHandler = {
addFiles: function (files) {
Object.keys(files).forEach(function (key) {
var file = files[key];
uploadHandler(files[key]);
});
},
drop: function(...) {...}
};
This would then define both of these functions:
uploader.fileHandler.addFiles()
uploader.fileHandler.drop()

knockoutjs save multiple viewmodels from one function?

I have spent the last few days researching the following KnockoutJS issue.
I have a page with 3 viewmodels on. I am using div's with id's to specify the bindings i.e:
ko.applyBindings(new viewModel(datasource), $("#sectionQualifications")[0]);
I am also using RequireJS which has really helped with making my app modular and works well with KnockoutJS of course.
My question relates to having (as mentioned) 3 viewmodels on my page.. none overlap, but each viewmodel has a SAVE function. So a quick look at one of the viewmodel snippets:
function viewModel(data) {
self = this;
self.quals = ko.observableArray(data),
self.addQual = function () {
self.quals.push(new qualification());
},
self.remove = function (item) {
// Remove from the database IF we have an actual record in our viewmodel
if (item.Id !== 0) {
dataservice_qualifications.deleteEntity(item.Id, ko.toJSON(item),
{
success: function (ret) {
common.notifyOK('Qualification removed');
},
error: function (err) {
common.notifyError('Cannot remove that qualification');
console.log('Qualification Remove Error', err);
console.log('Remove error object', this.Id);
}
}
);
}
// Remove from the actual view model
self.quals.remove(item);
}
// Save and move on.. we need to iterate through the qualifications, update any existing rows (ID NOT 0) or
// add new entries (ID IS 0)
self.save = function () {
var saveData = ko.toJS(this.quals);
for (var i in saveData) {
// New qualification entry
if (saveData[i].Id === 0) { // New qualification entry
dataservice_qualifications.postEntity(ko.toJSON(saveData[i]),
{
success: function (ret) {
},
error: function (error) {
common.notifyError('Cannot add qualification ' + saveData[i].qualificationName);
console.log('Qualification add error', error);
}
}
);
} // eof NEW qualification
if (saveData[i].Id > 0) {
dataservice_qualifications.putEntity(saveData[i].Id, ko.toJSON(saveData[i]),
{
success: function (ret) {
},
error: function (error) {
common.notifyError('Cannot update qualification ' + saveData[i].qualificationName);
console.log('UPDATED: ERROR:', error);
}
}
);
} // eof UPDATED qualification
} // eof saveData loop
common.notifyOK('Qualifications updated');
} // eof savenext function
return;
};
So from that above sample, I would have 2 other viewmodels that are similar, which have the SAVE function as above. So of course I want to use say jQuery to click a button and save all 3 viewmodels (i.e. via that SAVE function on each).
Because I am using RequireJS, I have tried exposing a "public" function that in turn tries to internally call the viewModel.save() function as follows in this snippet:
function saveModel() {
viewModel.save();
}
// PUBLIC INTERFACE
return {
saveModel: saveModel,
loadViewModel: koMapData
}
So the theory being I can call the "saveModel" function from wherever which should trigger the save of the viewmodels?
Any help really appreciated. By the way I have gone down the path of trying to create the viewmodel like:
var viewModel = {
save: function() {
blah blah...
}
}
however no real luck in that either? I am sure I am missing something simple, because I would think you could/should be able to trigger a function from a viewmodel externally somehow?
EDIT
Just for reference, the models DO NOT overlap..
Thanks in advance,
David.
You can merge view models in an object like this:
var mainVModel = {
vModel1: { // has save method},
vModel2: { // has save method},
saveAll : function(){
mainVModel.vModel1.save();
mainVModel.vModel2.save();
}
}
ko.applyBindings(new mainVModel());
Actually thanks #XGreen for your suggestion, and I can see that working well, however I am using requirejs, and so my app structure isn't quite a match.
However, I have been successful in the following solution:
First, I created the viewmodel in a slightly different way..
var viewModel = {
quals: ko.observableArray([]),
addQual: function () {
viewModel.quals.push(new qualification());
},
remove: function (item) {
// Do the remove bit..
},
save: function () {
var saveData = ko.toJS(viewModel.quals);
// Do the save stuff..
} // eof savenext function
}; // eof viewModel def
So the viewmodel is defined, and then I had a helper function to access just the SAVE function of the viewmodel:
// Private: Allows external access to save the viewmodel
var viewModelFunctions = {
saveModel: function () {
viewModel.save();
}
}
.. and then finally, because I am using the revealing module pattern within the requirejs structure, I created a public interface function as follows:
function koMapData(incomingData) {
datasource = (incomingData === null) ? [new qualification()] : incomingData;
viewModel.quals = ko.observableArray(ko.toJS(datasource));
ko.applyBindings(viewModel, $("#sectionQualifications")[0]);
}
// PUBLIC INTERFACE
return {
viewModelFunctions: viewModelFunctions,
loadViewModel: koMapData
}
So you can see the last part with the viewModelFunctions, which means in another module (or wherever) I can reference/trigger the SAVE function remotely by:
mymodule.viewModelFunctions.saveModel()
Which also means (in my case because I have 3 viewmodels I need to trigger save for from one event) I can have the flexibility of saving when/how I want to. Obviously it would be good to return any errors too etc up to the calling module, but that is in principle how it works for me.

Categories

Resources