In my mobile app, I have a drawer on my login page that allows the user to set the server to connect to. All works well except in one situation.
If I log in, then decide to logout, then change the settings (which are saved to local storage), then try to log in again, it logs in, but the add catalog throws and error.
Error: Error processing catalog 'servername.mydomain.com:8980/.../MyAppService.json'.
A service named 'MyAppService' was already loaded.
I'm using an angularjs factory as an authentication service and have the jsdosession as a property of it and I am currently just using anonymous security.
var factory = {
loginPath: '/login',
user: {
isAuthenticated: false,
roles: null
},
serverName: jsdoSettings.serverName,
serverPort: jsdoSettings.port,
serverSecure: jsdoSettings.secured,
jsdosession: createSession()
};
function createSession() {
// this will just set the authenticationModel to "ANONYMOUS" if it is bland or undefined
progress.util.jsdoSettingsProcessor(jsdoSettings);
if (!jsdoSettings.authenticationModel) {
console.log("Warning: jsdoSettings.authenticationModel not specified. Default is ANONYMOUS");
} else {
if (jsdoSettings.serviceURI) {
return new progress.data.JSDOSession(jsdoSettings);
} else {
console.log("Error: jsdoSettings.serviceURI must be specified.");
}
}
return null;
}
Here are the login and logout functions:
factory.login = function (username, password) {
var loggedIn = false;
var deferred = $q.defer();
try {
// factory.jsdosession = null;
// factory.jsdosession = createSession();
factory.jsdosession.login(username, password).done(
function (jsdosession, result, info) {
try {
console.log("login promise done");
factory.jsdosession.addCatalog(jsdoSettings.catalogURIs).done(
function (jsdosession, result, details) {
console.log("Add catalog promise done");
loggedIn = true;
changeAuth(loggedIn);
deferred.resolve(loggedIn);
}).fail(function (jsdosession, result, details) {
console.log("add catalog promise failed");
addCatalogErrorFn(jsdosession, progress.data.Session.GENERAL_FAILURE, details);
deferred.reject(loggedIn);
});
} catch (ex) {
console.log("undknown error in add catalog");
details = [{
"catalogURI": jsdoSettings.catalogURIs,
errorObject: ex
}];
addCatalogErrorFn(jsdosession, progress.data.Session.GENERAL_FAILURE, details);
deferred.reject(false);
}
}).fail(function (jsdosession, result, info) {
console.log("login promise failed");
loginErrorFn(jsdosession, result, info);
deferred.reject(false);
}); // end promise.fail
} catch (ex) {
loginErrorFn(jsdosession, progress.data.Session.GENERAL_FAILURE, {
errorObject: ex
});
deferred.reject(false);
}
return deferred.promise;
};
factory.logout = function () {
var promise,
loggedIn = true,
deferred = $q.defer();
try {
promise = factory.jsdosession.logout();
promise.done(function (jsdosession, result, info) {
console.log("logout promise done");
//vm.options.performLogout = false;
loggedIn = false;
deferred.resolve(true);
});
promise.fail(function (jsdosession, result, info) {
logoutErrorFn(jsdosession, result, info);
deferred.reject(false);
});
} catch (ex) {
logoutErrorFn(factory.jsdosession, progress.data.Session.GENERAL_FAILURE, {
errorObject: ex
});
deferred.reject(false);
}
changeAuth(loggedIn);
return deferred.promise;
};
And here is what I do when they change the settings (which will only happen when they are logged out.
factory.SaveServerSetup = function () {
jsdoSettings.SetServerInfo(factory.serverName, factory.serverPort, factory.serverSecure);
factory.jsdosession = createSession();
};
So, I am trying to just create a new JSDOSession object. I then click on the login button and it calls login, the login function is successful, but it fails on the addCatalog function stating the before-metioned error.
Is there something wrong in my setup or a bug in the progress.all.js or something else going on here?
Thanks
The logout() function does not clear any existing catalog information that has already been loaded, which is global to the app and not tightly tied to the JSDOSession. Therefore, if you log out and then log back in and try to load the same catalog, you get the error that you are seeing. We have discussed, but have not yet implemented, adding a function to the JSDOSession to allow you to clear the catalog. However, I think in your case you could clear the catalog yourself by doing the following:
progress.data.ServicesManager._services = [];
progress.data.ServicesManager._resources = [];
progress.data.ServicesManager._data = [];
progress.data.ServicesManager._sessions = [];
This should completely clear out the catalog, so if you call addCatalog() on the same catalog again, it will work. Note that after you clear the catalog, any JSDOs that the app still has will probably be unusable, so you will need to be sure to create new ones.
--Wayne
The logout() function does not clear any existing catalog information that has already been loaded, which is global to the app and not tightly tied to the JSDOSession. Therefore, if you log out and then log back in and try to load the same catalog, you get the error that you are seeing. We have discussed, but have not yet implemented, adding a function to the JSDOSession to allow you to clear the catalog. However, I think in your case you could clear the catalog yourself by doing the following:
progress.data.ServicesManager._services = [];
progress.data.ServicesManager._resources = [];
progress.data.ServicesManager._data = [];
progress.data.ServicesManager._sessions = [];
This should completely clear out the catalog, so if you call addCatalog() on the same catalog again, it will work. Note that after you clear the catalog, any JSDOs that the app still has will probably be unusable, so you will need to be sure to create new ones.
--Wayne
That does get me past that error, but then (and I'm pretty sure it is because I am calling new Progress.data.JSDOSession again), when I go to do one of my rest api calls, I get an error: Attempted to make server request when there is no active session.
If I try to create another progress.data.JSDOSession (the only way I can specify a new serviceURI that I can see), then I get this. Is there a way to reset this or something?
Thanks!
Are you making the REST api calls through a JSDO? Is that the same JSDO that you used before logging out? If so, that may be the problem. You will need to create a new JSDO after the second login and use that one. Otherwise, I am not sure what is going on, but would be glad to look at more of your code.
Good call. I have my jsdo's stored in services and I had some that I am using for dropdown data that I did not recreate the jsdo before making the request, like I do for the main jsdo. Once I did it for those, it works.
Thanks for the prompt and VERY useful help whenshaw!