I defined the RequireJS module (see below). This is the set of functions that are needed on every page of the site.
One of the functions in the returned object, initTwitter (), must call another function, shorttenURL (), in the same object. I get a console error: "TypeError: this.shortenURL is not a function."
All of these functions were originally in a regular singleton Javascript object, and the code worked fine. I'm new to RequireJS, so I'm not sure if the this keyword works differently in RequireJS, or I'm just doing something wrong.
EDIT: I also tried removing "this", but instead I get the message "ReferenceError: shortenURL not defined".
define(['config', 'jquery'], function(config, $) { return { doesObjPropertyExist: function(obj, prop) { var parts = prop.split('.'); for(var i = 0, l = parts.length; i < l; i++) { var part = parts[i]; if(obj !== null && typeof obj === "object" && part in obj) { obj = obj[part]; } else { return false; } } return true; }, shortenURL: function(longURL, callback, settingsOverride) { var defaults = { login: '@ bitly.username@ ', apiKey: '@ bitly.key@ ' }; $.extend({}, defaults, settingsOverride); var bitly_service_url = "http://api.bit.ly/v3/shorten?" + "&login=" + defaults.login + "&apiKey=" + defaults.apiKey + "&longUrl=" + longURL + "&format=json&callback=?"; $.getJSON(bitly_service_url, function(results){ if (results.status_txt === "OK") { callback(results.data["url"]); } else { callback(longURL); } }); }, initTwitter: function() { var bitly_obj = '', $bitly_link = '', twitterShortenUrl = function(obj, $elem) { this.shortenURL(obj.url, function(url) { $elem.attr('href', 'http://twitter.com/home?status=' + 'From @Real_Simple ' + arg_obj.headline + ' ' + shortened_url); }); }; $bitly_link = $('#share-twitter'); if ($bitly_link.length) { bitly_obj = config.page_context.bitly; twitterShortenUrl(bitly_obj, $bitly_link); } }, initFullSiteLink: function() { var canonical_url = $('link[rel="canonical"]').attr('href'), content_type = config.markup_id.content; if (content_type == 'search') { $('#fullsite').attr('href', canonical_url + location.search + '&nomobile=1'); } else { $('#fullsite').attr('href', canonical_url + '?nomobile=1'); } }, initNav: function() { $('#channels-toggle').bind('click', function() { if ($('#channels').hasClass('is-open')) { $('#channels').removeClass('is-open'); } else { $('#channels').addClass('is-open'); } return false; }); $('#channels .close').bind('click', function() { $('#channels').removeClass('is-open'); return false; }); }, omniture: { mobilePageTrack: function (desc) { omniPg(desc); } }, init: function() { this.initNav(); this.initTwitter(); this.initFullSiteLink(); } } });
EDIT 2: It turns out that โthisโ in my code was inside another function, so its scope changed to a window. I need to save the volume of this before entering the function.
initTwitter: function() { var bitly_obj = '', $bitly_link = '', self = this; var twitterShortenUrl = function(obj, $elem) { self.shortenURL(obj.url, function(url) { $elem.attr('href', 'http://twitter.com/home?status=' + 'From @Real_Simple ' + obj.headline + ' ' + url); }); };
Otherwise, Paulโs answer emphasizes that I can return anything and add initialization.