Better way of making javascript function a property - javascript

I was wondering if there was a way to use the get function in the url object below to generate property without wrapping it in an anonymous function.
It may be because I am just starting to dig into JavaScript after starting with jQuery, but something seems weird about wrapping a property in a anonymous function just to concatenate a string.
Current Object
var app = {
settings: {
webservice: 'http://abc.com/webservice/',
url: {
get: function (method) {
return app.settings.webservice + method;
},
caseSearch: function () {
return this.get('GetCases');
},
tipSearch: function () {
return this.get('GetTips');
},
propertySearch: function () {
return this.get('GetProperty');
}
}
}
};
Current
var url = app.settings.url.caseSearch();
Proposed
var url = app.settings.url.caseSearch;

Related

function expression with namespace

Actually I am trying to have a namspace [to avoid global variables] without object creation and trying to do the below. But, the execution of the methods data.sum and data.calc.mult with alerts is not getting called. Instead the empty declarations inside data are called. Can I anyone help me know why this is happening?
var data = {
name: "",
sum: function() {},
calc : {
mult: function() {}
}
};
data.sum();
data.calc.mult();
data.sum = function () {
alert('sum');
};
data.calc.mult = function () {
alert('mult');
};
If you put your data.sum() after data.sum function redefinition, you will get the alert box.
Define it like this (function definition within object definition):
var data = {
sum: function () {
alert('sum');
},
mult: function () {
alert('mult');
}
};
data.sum();
data.mult();

Configuring a service that depends on another service angularjs

What I need to know is how can I use a service like $http outside of the $get function or is it even possible? My code goes and loads a json file that provides a dictionary that my application makes use of in various ways. I want users to be able to customize this dictionary so I'm using jquery's extend method to allow users to add values to an object and extend the dictionary. The instantiate method in the code below handles all of this. What I'd like to be able to do is configure my service like so
config(['_sys_dictionaryProvider', function(_sys_dictionaryProvider) {
_sys_dictionaryProvider.instansiate('config/dictionary/custom/dictionary.json');
}])
But this requires the $http service to be available at the time of configuration and I don't think it is. If I put the $http service as part of the $get property it will work, as explained here, except then the network has to be queried every time the service is used. Is there any way to use a service in the configuration of another service?
Full code below, let me know if I need to clarify.
app.provider("_sys_dictionary", ['$http',
function ($http) {
var dictionary,
DictionaryService = function () {
this.definitions = dictionary;
this.define = function (what) {
var definitions = this.definitions;
if (what instanceof Array) {
for (var i = 0; i < what.length; i++) {
definitions = definitions[what[i]];
}
return definitions;
}
return this.definitions[what];
};
};
return {
$get: function () {
return new DictionaryService();
},
instansiate: function (path) {
$http.get('config/dictionary/dictionary.json').success(function (data) {
dictionary = data;
$http.get(path).success(function (data) {
jQuery.extend(true, dictionary, data)
});
});
}
};
}
]);
Seeing as I don't believe it is possible to use a service in the configuration stage, since there is no way to guarantee that the service your using itself has been configured, I went this route instead
app.provider("_sys_dictionary", function () {
var dictionary,
DictionaryService = function () {
this.definitions = dictionary;
this.define = function (what) {
var definitions = this.definitions;
if (what instanceof Array) {
for (var i = 0; i < what.length; i++) {
definitions = definitions[what[i]];
}
return definitions;
}
return this.definitions[what];
};
};
return {
$get: [
function () {
console.log(dictionary);
return new DictionaryService();
}
],
instansiate: function (path) {
jQuery.ajax({
url: 'config/dictionary/dictionary.json',
success: function (data) {
dictionary = data;
jQuery.ajax({
url: path,
success: function (data) {
jQuery.extend(true, dictionary, data);
},
async: false
});
},
async: false
});
}
};
});
I ended up using jquery's ajax object and turned async to false since I need the dictionary to be ready before the service gets used. Hope this helps someone. If anyone knows a better way of doing this I'd love to know.

Unfamiliar syntax in javascript object

My question:
var nsPreferences = {
property1:"",
get mPrefService()
{
return Components.classes["#mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
},
setBoolPref: function (aPrefName, aPrefValue)
{
try
{
this.mPrefService.setBoolPref(aPrefName, aPrefValue);
}
catch(e)
{
}
},
getBoolPref: function (aPrefName, aDefVal)// Prefs.jsで使用
{
try
{
return this.mPrefService.getBoolPref(aPrefName);
}
catch(e)
{
return aDefVal != undefined ? aDefVal : null;
}
return null; // quiet warnings
},
};
In this object nsPreferences, what is this "get mPrefService(){}"? This is the first time I've seen this kind of syntax in javascript object. Would anyone tell me about this syntax?
It's a getter function. It will look like a variable when you read it:
var someService = nsPreferences.mPrefService;
It calls that function without using the regular invocation parens. You can also use the set operator to create a "setter" function for the same property:
set mPrefService(val){
this.actualVal = val;
},
nsPreferences.mPrefService = "service";

Why has the author of this code used the .call method? Surely he could have just accessed the prototype?

Im looking through some code (unfortunatly the author isnt around anymore) and im wondering why he has used the .call method.
hmlPlaylist.prototype.loadVideos = function () {
var scope = this;
this.config.scriptUrl = '_HMLPlaylistAjax.aspx?' + Math.random();
jQuery.ajax({
type: 'GET',
url: this.config.scriptUrl,
success: function (d, t, x) {
scope.loadVideos_callback.call(scope, d);
},
error: function () {
}
});
};
hmlPlaylist.prototype.loadVideos_callback = function (data) {
var jsonData = '';
var jsonError = false;
try {
jsonData = eval("(" + data + ")");
} catch (jError) {
jsonError = true;
}
if (!jsonError) {
if (jsonData.playlists.length > 0) {
this.buildPlaylistList(jsonData.playlists);
}
if (jsonData.videos.length > 0) {
this.buildVideoList(jsonData.videos);
this.bindVideoNavs();
}
}
else {
// no json returned, don't do anything
}
};
Obviously he seems to have used it to pass a 'this' reference to the loadVideos_callback method but why? The 'loadVideos_callback' method is attached to the prototype of 'hmlplaylist' which is the 'class'. So if you access this inside the 'loadVideos_callback' method you get to the same thing dont you?
yes, I think you are right (I can't see the code in action). You still need the closure around scope, but in this case the use of call is not necessary.
To pull some of the comments into this answer, this is always the context on which the method was invoked. So if a new instance of htmlPlayList was created, and the method invoked on that instance, this would be a reference to that instance.

Resolve function pointer in $(document).ready(function(){}); by json string name

I have a json object retrieved from server in my $(document).ready(...); that has an string that I would like to resolve to a function also defined within $(document).ready(...); so, for example:
$(document).ready(function{
$.getJSON(/*blah*/,function(data){/*more blah*/});
function doAdd(left,right) {
return left+right;
}
function doSub(left,right) {
return left-right;
}
});
with json string:
{"doAdd":{"left":10,"right":20}}
One way I thought about was creating an associative array of the function before loading the json:
var assocArray=...;
assocArray['doAdd'] = doAdd;
assocArray['doSub'] = doSub;
Using eval or window[](); are no good as the function may not be called for some time, basically I want to link/resolve but not execute yet.
Change your JSON to
{method: "doAdd", parameters : {"left":10,"right":20}}
Then do
var method = eval(json.method);
// This doesn't call it. Just gets the pointer
Or (haven't tried this)
var method = this[json.method]
How about something like this?
$(function(){
// Function to be called at later date
var ressolvedFunc = null;
// Ajax call
$.getJSON(/*blah*/,function(data){
// Generate one function from another
ressolvedFunc = (function(data) {
var innerFunc;
var left = data.left;
var right = data.right;
// Detect action
for (action in data) {
if (action == "doAdd")
innerFunc = function() {
return left + right;
};
else
innerFunc = function() {
return left - right;
};
}
return innerFunc;
})(data);
});
});
The anonymous function returns fresh function, with the new values stored within the enclosure. This should allow you to call the function at later date with the data previously retrieved from the GET request.
Rich
try this:
var doX = (function() {
var
data = [],
getDo = function(action) {
for(var d in data) {
if (data[d][action]) {
return data[d];
}
}
return null;
};
return {
set: function(sdata) {
data.push(sdata);
},
doAdd: function() {
var add = getDo("doAdd");
if (!add)
return 0;
return add.doAdd.left + add.doAdd.right;
},
doSub: function() {
var sub = getDo("doSub");
if (!sub)
return 0;
return sub.doAdd.left + sub.doAdd.right;
}
};
})();
$(document).ready(function{
$.getJSON(/*blah*/,function(data){ doX.set(data); });
});

Categories