I have some circular dependencies in my Titanium application like so:
index.js
var Auth = require('Auth')
Auth.js
var PopUp = require('PopUp');
function isLoggedIn() {
// some logic e.g. return userName !== null
};
function authorise() {
if (isLoggedIn()) {
return true;
} else {
return PopUp.authorise();
}
}
PopUp
var Auth = require("Auth");
function authorise() {
// some code asking user to login
}
function showSecurePopUp() {
if (Auth.isLoggedIn()) {
// show secure pop up
}
}
As you can see we have a circular dependency. Auth needs PopUp and PopUp needs Auth.
This creates a circular dependency and thus the following error message:
[ERROR] [iphone, 10.3.3, 192.168.0.64]
Type: RangeError
Message: Maximum call stack size exceeded.
File: /iphone/Auth.js.js
Line: 24
How can I solve the issue of circular dependencies in a Titanium Alloy app?
I think this could be the way, you do the following changes in you project and this should solve the problem.
Alloy.js
var Auth = require("Auth");
var PopUp = require('PopUp');
Index.js
Auth.authorise();
Auth.js
var isLoggedIn = function() {
// some logic e.g. return userName !== null
Ti.API.info('isLoggedIn');
return false;
};
exports.authorise = function() {
if (isLoggedIn()) {
Ti.API.info('authorize isloggedIn');
return true;
} else {
Ti.API.info('authorize not logged In');
return PopUp.authorise();
}
};
exports.isLoggedIn = isLoggedIn;
PopUp.js
exports.authorise =function () {
// some code asking user to login
Ti.API.info('authorize funcition popup ' + Auth.isLoggedIn());
};
function showSecurePopUp() {
if (Auth.isLoggedIn()) {
// show secure pop up
Ti.API.info('isLoggedIn show secure popup');
}
}
Let me know if this works fine and if this is what you wanted. Also if you have some other approach that solves the problem, then let me know that also.
Good Luck & Cheers
Ashish Sebastian
Related
I am trying to integrate google-recaptcha but no success.
Getting error
feedback.js:39 Uncaught TypeError: grecaptcha.render is not a function
main.js
'googlerecaptcha':'https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit',
define(['ojs/ojcore', 'knockout', 'jquery', 'appController', 'ckeditor', 'googlerecaptcha', 'ojs/ojlabel',
'ojs/ojknockout', 'ojs/ojinputtext', 'ojs/ojformlayout'],
function (oj, ko, $, app, ckeditor, grecaptcha) {
/**
* The view model for the main content view template
*/
function feedbackViewModel() {
var self = this;
// For small screens: labels on top
// For medium screens and up: labels inline
this.labelEdge = ko.computed(function () {
return app.smScreen ? "top" : "start";
}, this);
onloadCallback = function (a) {
grecaptcha.render('submit', {
'sitekey': 'YOUR_API_KEY',
'callback': self.onSubmit
}, true);
};
this.handleActivated = function (info) {
};
self.onSubmit = function (token) {
console.info("google recatpcha onSubmit", token)
//do validation/application code using token
var data = {secret: grecaptcha, response: recaptchaToken};
$.post({
url: "https://www.google.com/recaptcha/api/siteverify",
form: data
}).then(function (e) {
//recaptcha service called...check result
var resp = JSON.parse(e);
if (resp.success == false) {
console.info("recaptcha token outcome is false")
} else {
console.info("recaptcha token validated")
}
});
};
}
return feedbackViewModel;
});
Do you have a mapping for 'googlerecaptcha' in src/js/path_mapping.json? If I go to https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit, I do not see that it is returning any valid object. So most likely 'grecaptcha' variable is undefined.
reCaptcha + RequireJS
Looks like reCaptcha is a function that has to be executed vs an object that can be interacted with directly. So you may need a different approach, something mentioned in this thread.
We have single sign on enabled for our MS Dynamics 365 CRM instance to make a calls to an API hosted in Azure. On launch of CRM we have the following JavaScript that executes. This works most of the time, but on occasion we get "Invalid argument" popup. I am relatively new to using Adal.js and have no idea what is causing this. Any trouble shooting tips appreciated. Thanks in advance.
config = {
ApiUrl: configData["ApiUrl"],
SubscriptionKey: configData["SubscriptionKey"],
trace: configData["trace"],
AcceptHeader: configData["AcceptHeader"],
ContentTypeHeader: configData["ContentTypeHeader"],
tenant: configData["tenant"],
clientId: configData["clientId"],
tokenStoreUrl: configData["tokenStoreUrl"],
cacheLocation: configData["cacheLocation"],
GraphApi: configData["GraphApi"]
};
// Check For & Handle Redirect From AAD After Login
authContext = new window.AuthenticationContext(config);
var isCallback = authContext.isCallback(window.location.hash);
if (isCallback) {
authContext.handleWindowCallback();
}
var loginError = authContext.getLoginError();
if (loginError) {
console.log('ERROR:\n\n' + loginError);
}
authContext.popUp = true;
if (isCallback && !loginError) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}
var user = authContext.getCachedUser();
if (!user) {
authContext.clearCache();
sessionStorage["adal.login.request"] = "";
authContext.login();
}
window.parent.authContext = authContext;
It has been a while since I last looked at this, however I managed to get it resolved at the time. I implemented a locking mechanism, to ensure the login completes before trying to obtain a token.
Here is the updated code:
config = {
ApiUrl: configData["ApiUrl"],
SubscriptionKey: configData["SubscriptionKey"],
trace: configData["trace"],
AcceptHeader: configData["AcceptHeader"],
ContentTypeHeader: configData["ContentTypeHeader"],
tenant: configData["tenant"],
clientId: configData["clientId"],
tokenStoreUrl: configData["tokenStoreUrl"],
cacheLocation: configData["cacheLocation"],
GraphApi: configData["GraphApi"],
loadFrameTimeout: 10000
};
// Check For & Handle Redirect From AAD After Login
authContext = new window.AuthenticationContext(config);
var isCallback = authContext.isCallback(window.location.hash);
if (isCallback) {
authContext.handleWindowCallback();
}
var loginError = authContext.getLoginError();
if (loginError) {
// TODO: Handle errors signing in and getting tokens
console.log('ERROR:\n\n' + loginError);
}
authContext.popUp = true;
if (isCallback && !loginError) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}
var user = authContext.getCachedUser();
if (!user) {
authContext.clearCache();
sessionStorage["adal.login.request"] = "";
authContext.callback = function (error, token, msg) {
// remove lock
window.top.loginLock = null;
if (!!token) {
getGraphApiTokenAndUpdateUser(authContext);
}
else {
console.log('ERROR:\n\n' + error);
}
};
if (typeof (window.top.loginLock) == "undefined" || window.top.loginLock == null) {
// Create lock
window.top.loginLock = true;
authContext.login();
}
}
window.parent.authContext = authContext;
I am facing a problem which I am not aware how to resolve. Let me describe elaborately below:
I have a commonViewModel kendo class where event like save, cancel are written. I am facing problem with the save event of this class.
save: function () {
var that = this;
var routeLanguage = "";
that._showBackConfirmation(false);
that.set("isFormSubmitted", true);
console.log("form is valid, sending the save request!");
if (vm.get("languageTabsVm.selectedLanguage")) {
routeLanguage = "/" + vm.get("languageTabsVm.selectedLanguage");
}
else if (that.get("model.Languages") && that.get("model.Languages").length > 1) {
that.get("model.Languages").forEach(function (lang) {
if (lang.get("IsActive") === true) {
//sätt cv-visning till det språk jag senast redigerade på detta item
routeLanguage = "/" + lang.LanguageId;
}
});
}
//if i call the function _loadDefaultLanguageSelection here, it
// works. because, the datasource is not synced yet.
//Make sure the datasource are syncing changes to the server (includes all crud)
return that.dataSource.sync().fail(function (e) {
//i need to do something here to be in the same language tab. But
//as i am changing directly in to model, it is not possible. But
//saving directly to model is essential because that model is
//shared to other viewmodel for language tab synching purpose.
that.set("isFormSubmitted", false);
console.log("form rejected");
}).done(function () {
if (that.get("isPersonaldetail")) {
var name = that.get("model.Name");
if (name.length > 12)
name = name.substring(0, 11) + "...";
$("#profileName").text(name);
}
that.set("isFormSubmitted", false);
that.set("isSelected", false);
// it is called from here right now. but it is failing because
// model is updated but not synced in that function
that._loadDefaultLanguageSelection();
router.navigate(that.nextRoute + routeLanguage);
});
},
_loadDefaultLanguageSelection: function () {
var that = this;
if (that.get("model.Languages") && that.get("model.Languages").length > 1) {
that.get("model.Languages").forEach(function (lang) {
if (!that.get("isPersonaldetail")) {
lang.set("IsActive", lang.get("LanguageId") === vm.get("languageTabsVm.selectedLanguage"));
}
});
}
},
So, my question is, how can i resolve this problem. one solution is i will have to sync twice. that is not nice. So, I am looking for efficient solution.
I would like to know if I am missing anything with regard to sinon.js I have tried using sinon.stub().returns and yields but am unable to get the result. Any pointers would be helpful
I have a module which calls another module that returns the value from the DB
var users = require('/users');
module.exports.getProfileImage = function (req, res) {
var profile = {};
else {
users.findOne("email", req.session.user.email, function (err, user) {
if (err) {
res.status(400).send();
}
else if (!user) {
//return default image
}
else if (user) {
//Do some other logic here
}
});
};
I am using mocha as the testing framework and am also using sinon. The problem that I am facing is when i create a stub of users.findOne to return a value the control does not come to my else if (user) condition.
my unit test case is as follows
describe("Return image of user",function(){
var validRequest = null;
validRequest={
session:{
user:{
email:'testUser#test.com',
role:'Hiring Company'
}
}
};
it("Should return an image from the file if the user is present in db",function(done){
var findOneUserResponse ={
companyName:"xyz",
email:"xyz#abc.com"
};
var findOne = sinon.stub(mongoose.Model, "findOne");
findOne.callsArgWith(1,null,findOneUserResponse);
user.getProfileImage(validRequest,response);
var actualImage = response._getData();
findOne.restore();
done();
};
};
So I went through the sinon.js documentation http://sinonjs.org/docs/ and came across what I was missing
describe("Return image of user",function(){
var validRequest = null;
validRequest={
session:{
user:{
email:'testUser#test.com',
role:'Hiring Company'
}
}
};
it("Should return an image from the file if the user is present in db",function(done){
var findOneUserResponse ={
companyName:"xyz",
email:"xyz#abc.com"
};
var findOne = sinon.stub(mongoose.Model, "findOne",function(err,callback){
callback(null,findOneUserResponse);
)};
user.getProfileImage(validRequest,response);
var actualImage = response._getData();
findOne.restore();
done();
};
};
ok so im having a hard time hiding some layout sections (divs in my layout page and im using mvc3).
I have this js fragment which is basically the main logic:
$('.contentExpand').bind('click', function () {
$.cookie('right_container_visible', "false");
});
//Cookies Functions========================================================
//Cookie for showing the right container
if ($.cookie('right_container_visible') === 'false') {
if ($('#RightContainer:visible')) {
$('#RightContainer').hide();
}
$.cookie('right_container_visible', null);
} else {
if ($('#RightContainer:hidden')) {
$('#RightContainer').show();
}
}
as you can see, im hidding the container whenever i click into some links that have a specific css. This seems to work fine for simple tests. But when i start testing it like
.contentExpand click --> detail button click --> .contentExpand click --> [here unexpected issue: the line $.cookie('right_container_visible', null); is read but it doesnt set the vaule to null as if its ignoring it]
Im trying to understand whats the right logic to implement this. Anyone knows how i can solve this?
The simpliest solution is to create variable outside delegate of bind.
For example:
var rightContVisibility = $.cookie('right_container_visible');
$('.contentExpand').bind('click', function () {
$.cookie('right_container_visible', "false");
rightContVisibility = "false";
});
if (rightContVisibility === 'false') {
...
}
The best thing that worked for me was to create an event that can catch the resize of an element. I got this from another post but I dont remember which one. Anyway here is the code for the event:
//Event to catch rezising============================================================================
(function () {
var interval;
jQuery.event.special.contentchange = {
setup: function () {
var self = this,
$this = $(this),
$originalContent = $this.text();
interval = setInterval(function () {
if ($originalContent != $this.text()) {
$originalContent = $this.text();
jQuery.event.handle.call(self, { type: 'contentchange' });
}
}, 100);
},
teardown: function () {
clearInterval(interval);
}
};
})();
//=========================================================================================
//Function to resize the right container============================================================
(function ($) {
$.fn.fixRightContainer = function () {
this.each(function () {
var width = $(this).width();
var parentWidth = $(this).offsetParent().width();
var percent = Math.round(100 * width / parentWidth);
if (percent > 62) {
$('#RightContainer').remove();
}
});
};
})(jQuery);
//===================================================================================================