i am trying to make a custom module based application myself.
1st the idea:
i want to have couple of modules which all will represent a file )
1 module: Object, with filename. Object.js
2nd module: Utils, with filename Utils.js
now as you can see in my code i am using get script to load all those files and prepare a global app object which i can use all accross my application.
However i want to combine all my js at the end of the development and minify it, so basically i dont know how to check ( and register ) those modules with requiring the file itself. Here are my app.js and my Object.js
app.js:
var shop = (function () {
'use strict';
var modules = [];
var getModulesDir = function () {
return document.location.origin + "/js/App/modules/"
}
var registerDefaultModules = function () {
modules.push({
name: "Object",
alias: "Object"
}, {
name: "Utils",
alias: "Utils"
});
};
var loadModules = function () {
jQuery.each(modules, function (key, module) {
if (module.name == "") {
console.error("loading script without name");
return true;
}
if (module.alias == "") {
module.alias = module.name;
}
if (typeof shop[module.alias] !== "undefined") {
return true;
}
window.moduleAlias = module.alias;
var path = "";
if (typeof module.path != "undefined") {
path = module.path;
}
if (path == "") {
path = getModulesDir() + module.name.split('.').join('/') + ".js";
}
$.getScript(path)
.done(function (script, textStatus) {
})
.fail(function (jqxhr, settings, exception) {
console.error('failed loading a script')
});
});
}
var init = function () {
registerDefaultModules();
loadModules();
}
return {
init: init
};
})();
jQuery(document).ready(function () {
shop.init();
});
Object.js
(function($, app) {
$(window).load(function(event) {
'use strict';
app.Object = {
getSize: function(object) {
var size = 0,
property;
for (property in object) {
if (object.hasOwnProperty(property)) {
size++;
}
}
return size;
}
}
return app;
});
})(jQuery, shop);
i could be totally wrong, and if so would be nice if someone show me the right way of doing it.
Related
File name Postman.js
"use strict";
define([], function() {
var postManSingleton = (function() {
var postManInstance
, createPostMan = function() {
var events = {};
return {
publish: function(event, payload) {
if(!events.hasOwnProperty(event))
return;
events[event].forEach(function(listener){
listener(payload || {});
});
},
subscribe: function(event, listener) {
if(!events.hasOwnProperty(event))
events[event] = [];
var index = events[event].push(listener)-1;
return {
remove: function () {
delete events[event][index];
}
}
}
}
};
return {
getInstance: function() {
if(!postManInstance)
postManInstance = createPostMan();
return postManInstance;
}
}
}());
return postManSingleton.getInstance();
});
Importing this file as in index.test.js
import * as Postman from 'postman.js';
How do I mock its publish and subscribe events in jest.
I have tried
jest.mock('Postman.publish', () =>({//some code}))
Error : Cannot find module Postman.publish from 'index.test.js'
Please help how it is possible to mock the above file. Is it even possible?
Your Postman.js is in AMD & Jest does not support AMD. So you need to convert AMD to commonjs.
You can use babel-plugin-transform-amd-to-commonjs for conversion.
I'm not much understand about this pattern yet so I try to check some Jquery plugin and follow their structure However I want to reuse this plugin.
Here is Code
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
}) (function ($) {
'use strict';
var console = window.console || { log: function () {} };
function Testing($element, $els) {
this.$Form = $($elementss);
this.$Input = this.$Form.find($els);
this.init();
}
Testing.prototype = {
constructor: Testing,
init: function () {
this.addListener();
},
addListener : function () {
this.$Input.on('change', $.proxy(this.changeIt, this));
},
changeIt: function (e) {
console.log(e)
}
};
$(function (e) {
return new Testing($('#form'), '.inputClass');
});
});
As the above I can call it on return new Testing($('#form'), '.inputClass'); But how can I do if i want to use it with another selectors.
Consider the following code in the official angular repository
function createInjector(modulesToLoad, strictDi) {
strictDi = (strictDi === true);
var testingScope = 'this is a test';
var INSTANTIATING = {},
providerSuffix = 'Provider',
path = [],
loadedModules = new HashMap([], true),
providerCache = {
$provide: {
provider: supportObject(provider),
factory: supportObject(factory),
service: supportObject(service),
value: supportObject(value),
constant: supportObject(constant),
decorator: decorator
}
},
providerInjector = (providerCache.$injector =
createInternalInjector(providerCache, function(serviceName, caller) {
if (angular.isString(caller)) {
path.push(caller);
}
throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
})),
instanceCache = {},
protoInstanceInjector =
createInternalInjector(instanceCache, function(serviceName, caller) {
var provider = providerInjector.get(serviceName + providerSuffix, caller);
return instanceInjector.invoke(
provider.$get, provider, undefined, serviceName);
}),
instanceInjector = protoInstanceInjector;
providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };
var runBlocks = loadModules(modulesToLoad);
instanceInjector = protoInstanceInjector.get('$injector');
instanceInjector.strictDi = strictDi;
forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); });
return instanceInjector;
And
function createInternalInjector(cache, factory) {
function getService(serviceName, caller) {
console.log(testingScope);
if (cache.hasOwnProperty(serviceName)) {
if (cache[serviceName] === INSTANTIATING) {
throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
serviceName + ' <- ' + path.join(' <- '));
}
return cache[serviceName];
} else {
try {
path.unshift(serviceName);
cache[serviceName] = INSTANTIATING;
return cache[serviceName] = factory(serviceName, caller);
} catch (err) {
if (cache[serviceName] === INSTANTIATING) {
delete cache[serviceName];
}
throw err;
} finally {
path.shift();
}
}
}
return {
get: getService,
};
}
We see that createInternalInjector is able to access local variables (like path) in its caller's scope createInjector without passing in to the parameter.
Indeed if I add testingScope to createInjector and try to access in createInternalInjector, I was able to do it.
This is weird because I try to replicate this behavior like the following.
testOuter();
function testOuter() {
var outer = 'outer'
testInner().test();
}
function testInner() {
function testing() {
console.log(outer);
}
return {
test: testing
}
}
But got an error instead.
ReferenceError: outer is not defined
Can someone give me some pointers on why this is happening?
The issue here is scope chaining. createInternalInjector function is called within createInjector function, therefore it can access its parent properties. In your case you have sibling functions that are unaware to each other variables.
More on scope chains and closures: https://stackoverflow.com/a/1484230/5954939
I'm working on an app and I'm playing around with Angular2 for fun. I'm using ES5 JavaScript, and my question right now is how do I access the Http service? All of the documentation available is TypeScript (which is not helpful) or it's for an alpha version of Angular2, and the system has changed since.
I'm using Angular2 version 2.0.0-beta.13. I am receiving the following error: TypeError: ng.http.get is not a function in [null]. I've tried using ng.http.Http.get to no avail. I have angular2-all.umd.js included in the head, as well as the other js requirements defined by angular.io (RxJS, es6 shims, polyfills, etc).
Here are the code snippets I have, for reference. All files are concatenated together for ease of reading.
;(function (app, ng) {
app.CommandService = (function () {
var CommandService = function () {
this.url = 'api/commands';
};
CommandService.prototype.all = function () {
return ng.http.get(this.url)
.map(function (response) {
return response.json().data;
})
.catch();
};
return CommandService;
})();
})(window.app || (window.app = {}), window.ng);
;(function (app, ng) {
app.CommandComponent = (function () {
function CommandComponent(commandService) {
this.commandService = commandService;
this.commands = [];
}
CommandComponent.parameters = [
app.CommandService
];
CommandComponent.annotations = [
new ng.core.Component({
selector: '#command-listing',
templateUrl: 'api/templates/commands/listing',
providers: [
app.CommandService,
ng.http.HTTP_PROVIDERS
]
})
];
CommandComponent.prototype.all = function () {
var self = this;
this.commandService.all().subscribe(
function (commands) {
self.commands = commands;
}, function (error) {
self.error = error;
}
);
};
CommandComponent.prototype.ngOnInit = function () {
this.all();
};
return CommandComponent;
})();
})(window.app || (window.app = {}), window.ng);
;(function (app, ng) {
document.addEventListener('DOMContentLoaded', function () {
ng.platform.browser.bootstrap(app.CommandComponent);
});
})(window.app || (window.app = {}), window.ng);
From a timing perspective, TypeScript does not seem to be a viable option. I tried to set up the environment as needed, and after a full day of debugging TS issues, I now have SystemJS issues, so I'm hoping the plain JS option can suffice for now until I have time to figure out all of the intricacies.
Let me know if more information is needed; I'm happy to give it.
Change your CommandService:
;(function (app, ng) {
app.CommandService = (function () {
var CommandService = function (http) { // this line changed
this.url = 'api/commands';
this.http = http; // this line added
};
CommandService.parameters = [ // this line added
ng.http.Http // this will be passed as arg in the constructor
]; // this line added
CommandService.prototype.all = function () {
return this.http.get(this.url) // this line changed
.map(function (response) {
return response.json().data;
})
.catch();
};
return CommandService;
})();
})(window.app || (window.app = {}), window.ng);
See plunker: http://plnkr.co/edit/4FG1Lrt7Yhnzo20azV8Z?p=preview
Just as an additional info, you could remove from the CommandComponent (line 41 of app/main.js) and add the ng.http.HTTP_PROVIDERS at the bootstrap() like this:
document.addEventListener('DOMContentLoaded', function () {
ng.platform.browser.bootstrap(app.CommandComponent, [ng.http.HTTP_PROVIDERS]);
});
I want to do something like $.ajax() success and error callbacks.
This is what I have so far:
var FileManager = {
LoadRequiredFiles: function (onLoadingCallback, onCompleteCallback) {
//Not sure what to do here
this.OnLoading = onLoadingCallback;
this.OnCompleteCallback = onCompleteCallback;
this.OnLoading();
this.OnComplete();
},
OnLoading: function () {
//empty by default
}
OnComplete: function () {
//empty by default
}
};
//I want to do something like this:
FileManager.LoadRequiredFiles({OnLoading: function() {
alert('loading');
}
});
How do I fix this up properly? I'm using FileManager as my namespace.
You can check if the functions are defined:
var FileManager = {
LoadRequiredFiles: function (config) {
config = config || {};
this.OnLoading = config.onLoadingCallback;
this.OnCompleteCallback = config.onCompleteCallback;
if(typeof this.OnLoading =='function') {
this.OnLoading();
}
//Or use the shortcut:
if(this.OnComplete) {
this.OnComplete();
}
}
};
FileManager.LoadRequiredFiles(
{
onLoadingCallback: function() {
alert('loading');
}
}
);