Node JS code not running in order - sql

I have no idea why the code do not run as I expected.
When the UserExist is called, it should either console.log one of the statements that I set in my function code.
But the result is like the following the picture. Apreciate that if somebody can help!!
Console
var sql = require('mssql');
var config = require('./configuration/sqlconfig');
var Username = "Testing";
sql.connect(config);
console.log("Connected to DB");
if (!UserExist(Username)) {
InsertNewRecord(Username);
}
function isEmptyObject(obj) {
return !Object.keys(obj).length;
}
// This should work both there and elsewhere.
function isEmptyObject(obj) {
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
return false;
}
}
return true;
}
function UserExist(Username) {
console.log('Checking whether user exists or not... ');
new sql.Request().query("SELECT * FROM dbo.DB_Users WHERE Username = '" + Username + "';")
.then(function (recordset) {
if (isEmptyObject(recordset)) {
console.log("The User does not exist, ready to insert");
return true;
} else {
console.log("The user is existed already.");
return false;
}
}).catch(function (err) {
//When errors come
});
}
function InsertNewRecord(Username) {
console.log('Attempting to Insert records...');
new sql.Request().query("INSERT INTO dbo.Embright_Users (Username) VALUES ('" + Username + "');");
console.log("Added one new record");
}

The callbacks are not chained correctly. The InsertNewRecord() should be passed as callback to UserExist() function to make sure the execute in sequence. eg:
// Calling UserExist with a callback instead of 'if' statement
UserExist(Username, InsertNewRecord)
function UserExist(Username, callback) {
console.log('Checking whether user exists or not... ');
new sql.Request().query("SELECT * FROM dbo.DB_Users WHERE Username = '" + Username + "';")
.then(function (recordset) {
if (isEmptyObject(recordset)) {
console.log("The User does not exist, ready to insert");
// Calling InsertNewRecord with the username passed
callback(Username);
} else {
console.log("The user is existed already.");
// Do nothing
}
}).catch(function (err) {
//When errors come
});
}

Related

How can I refresh datatable in Wire using refreshApex

#wire(_getContacts,{recordId:'$recordId'}) wiredContacts({error,data}){
this.dataToRefresh = data;
if (data) {
this.contacts = this.dataToRefresh.recordList;
this.ContactsRecords = this.dataToRefresh.cList;
this.contactsSize = " Case Contacts (" + this.contacts.length + ")";
}else{
//
}
};
relateContacts() {
this.showSpinner = true;
this.showtable=false;
relateContacts({contacts: this.selected, recordId: this.recordId})
.then(data => {
this.showSpinner=false;
this.showtable=true;
this.showSuccessMessage();
refreshApex(this.dataToRefresh);
//location.reload();
this.isShowModal = false;
})
.catch(error => {
console.log(error);
this.showSpinner=false;
const evt = new ShowToastEvent({
title: 'Application Error',
message: error.body.message,
variant: 'error',
mode: 'sticky'
});
this.dispatchEvent(evt);
this.showSpinner = false;
});
}
For this code, I tried refreshApex with all possible ways. but I'm not sure the miss here. I've Checked all the blogs but everywhere, the solution is mentioned.
Tried refreshApex like below :
#wire(_getContacts,{recordId:'$recordId'}) wiredContacts({data}){
this.dataToRefresh = data;
But this also does not work
Ah that is a fun one ! Your issue is using destructuring in wiredContacts as the parameter.
(The {data} or {data,error} normally works as a parameter to the function being called back, except if you have to do refresh) Try this instead.
#wire(_getContacts,{recordId:'$recordId'}) wiredContacts(value){
this.dataToRefresh = value;
const {data, error} = value;
//Rest of you code now with data and error
}
Then in your other method you can do:
method(){
refreshApex(this.dataToRefresh);
}
Salesforce does show doing this in their example code, but it’s easy to miss and experience the fun you have been having with this.
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.apex_result_caching
See the last example on their page.

Reading from one db into another

I am trying to right a function that copies some fields from several company databases into my own database once a day. What I have so far is below. I am wondering if where I console.log(rs) I can open another sql connection to my database and write the data or if I have to store the results somewhere and then open a new connection and send the stored results.
function updateJobs() {
var query = "SELECT JobStart, JobEnd FROM JobData";
sql.connect(Config, (err) => {
if (err) {
console.log("Error while connecting database :- " + err);
} else {
var request = new sql.Request();
request.query(query, function (err, rs) {
if (err) {
console.log("Error while querying database :- " + err);
sql.close();
} else {
console.log(rs);
sql.close();
}
})
}
})
}
This might help
// Source Database
sourceDB.each(`select * from ${Sourcetable}`, (error, row) => {
console.log(row);
const keys = Object.keys(row); // ['columnA', 'columnB']
const columns = keys.toString(); // 'columnA,columnB'
let parameters = {};
let values = '';
// Generate values and named parameters
Object.keys(row).forEach((r) => {
var key = '$' + r;
// Generates '$columnA,$columnB'
values = values.concat(',', key);
// Generates { $columnA: 'ABC', $columnB: 'GHK' }
parameters[key] = row[r];
});
// Insert into another database into OneTable (columnA,columnB) values ($columnA,$columnB)
// Parameters: { $columnA: 'ABC', $columnB: 'GHK' }
destDB.run(`insert into ${Desttable} (${columns}) values (${values})`, parameters);
})
})

Adal.js not setting props in localStorage

I'm having a problem using the adal.js library without Angular. (I'm using Vue.js.)
I have an authentication context instance, which is constructed with the following options (exact values have been changed to protect the innocent):
let config = {
tenant: '<tenant id>',
clientId: '<client id>',
redirectUri: 'http://myapplication.com/index.html',
// popUp: true,
cacheLocation: 'localStorage'
}
On my login page, I call authContext.login(), which redirects me first to https://login.microsoftonline.com/, where I log into AAD. Upon successful login, another redirect takes me back to my application, at the URI I've configured above, along with an id_token parameter in the URL. However, no token or other properties are stored by the library in local storage, just a few properties that are the result of the configuration.
On successful login, All I've got in localStorage is
{
adal.access.token.key: "",
adal.error: ""
adal.error.description: ""
adal.expiration.key: "0"
adal.idtoken: ""
adal.login.error: ""
adal.login.request: "http://myapplication.com/#/login"
adal.nonce.idtoken: "<a non-empty string>"
adal.session.state: ""
adal.state.login: "<a non-empty string>"
adal.token.keys: ""
adal.username: ""
}
So, as far as AAD is concerned, I've successfully authenticated, but the library itself seems to have no notion of what user is logged in, what tokens are associated with them, when the token expires, etc. Any advice on how to proceed would be most appreciated. Thank you in advance for reading.
Active Directory Authentication Library for JavaScript (ADAL JS) helps you to use Azure AD for handling authentication in your single page applications. This library is optimized for working together with AngularJS.
It will not save the tokens into the cache unless we code it. You can check the relative code from adal-angular.js. Here is a piece of code for your reference:
The saveTokenFromHash method will also save the tokens into cache and this function will execute after the page redirect back to the Angular app.
adal.js:
AuthenticationContext.prototype.saveTokenFromHash = function (requestInfo) {
this._logstatus('State status:' + requestInfo.stateMatch);
this._saveItem(this.CONSTANTS.STORAGE.ERROR, '');
this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, '');
// Record error
if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ERROR_DESCRIPTION)) {
this._logstatus('Error :' + requestInfo.parameters.error);
this._logstatus('Error description:' + requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]);
this._saveItem(this.CONSTANTS.STORAGE.FAILED_RENEW, requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]);
this._saveItem(this.CONSTANTS.STORAGE.ERROR, requestInfo.parameters.error);
this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]);
if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) {
this._loginInProgress = false;
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, requestInfo.parameters.errorDescription);
} else {
this._renewActive = false;
}
} else {
// It must verify the state from redirect
if (requestInfo.stateMatch) {
// record tokens to storage if exists
this._logstatus('State is right');
if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.SESSION_STATE)) {
this._saveItem(this.CONSTANTS.STORAGE.SESSION_STATE, requestInfo.parameters[this.CONSTANTS.SESSION_STATE]);
}
var keys, resource;
if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ACCESS_TOKEN)) {
this._logstatus('Fragment has access token');
// default resource
this._renewActive = false;
resource = this.config.loginResource;
if (!this._hasResource(resource)) {
keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || '';
this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER);
}
if (requestInfo.requestType === this.REQUEST_TYPE.RENEW_TOKEN) {
resource = this._getResourceFromState(requestInfo.stateResponse);
}
// save token with related resource
this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ACCESS_TOKEN]);
this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._expiresIn(requestInfo.parameters[this.CONSTANTS.EXPIRES_IN]));
}
if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ID_TOKEN)) {
this._loginInProgress = false;
this._user = this._createUser(requestInfo.parameters[this.CONSTANTS.ID_TOKEN]);
if (this._user && this._user.profile) {
if (this._user.profile.nonce !== this._getItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN)) {
this._user = null;
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, 'Nonce is not same as ' + this._idTokenNonce);
} else {
this._saveItem(this.CONSTANTS.STORAGE.IDTOKEN, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]);
// Save idtoken as access token for app itself
resource = this.config.clientId;
if (!this._hasResource(resource)) {
keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || '';
this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER);
}
this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]);
this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._user.profile.exp);
}
}
}
} else {
this._saveItem(this.CONSTANTS.STORAGE.ERROR, 'Invalid_state');
this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, 'Invalid_state');
if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) {
this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, 'State is not same as ' + requestInfo.stateResponse);
}
}
}
};
And this function will be called in this.$get like below:
// special function that exposes methods in Angular controller
// $rootScope, $window, $q, $location, $timeout are injected by Angular
this.$get = ['$rootScope', '$window', '$q', '$location', '$timeout', function ($rootScope, $window, $q, $location, $timeout) {
var locationChangeHandler = function () {
var hash = $window.location.hash;
if (_adal.isCallback(hash)) {
// callback can come from login or iframe request
var requestInfo = _adal.getRequestInfo(hash);
_adal.saveTokenFromHash(requestInfo);
$window.location.hash = '';
if (requestInfo.requestType !== _adal.REQUEST_TYPE.LOGIN) {
_adal.callback = $window.parent.AuthenticationContext().callback;
}
// Return to callback if it is send from iframe
if (requestInfo.stateMatch) {
if (typeof _adal.callback === 'function') {
// Call within the same context without full page redirect keeps the callback
if (requestInfo.requestType === _adal.REQUEST_TYPE.RENEW_TOKEN) {
// Idtoken or Accestoken can be renewed
if (requestInfo.parameters['access_token']) {
_adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['access_token']);
return;
} else if (requestInfo.parameters['id_token']) {
_adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['id_token']);
return;
}
}
} else {
// normal full login redirect happened on the page
updateDataFromCache(_adal.config.loginResource);
if (_oauthData.userName) {
//IDtoken is added as token for the app
$timeout(function () {
updateDataFromCache(_adal.config.loginResource);
$rootScope.userInfo = _oauthData;
// redirect to login requested page
var loginStartPage = _adal._getItem(_adal.CONSTANTS.STORAGE.START_PAGE);
if (loginStartPage) {
$location.path(loginStartPage);
}
}, 1);
$rootScope.$broadcast('adal:loginSuccess');
} else {
$rootScope.$broadcast('adal:loginFailure', _adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION));
}
}
}
} else {
// No callback. App resumes after closing or moving to new page.
// Check token and username
updateDataFromCache(_adal.config.loginResource);
if (!_adal._renewActive && !_oauthData.isAuthenticated && _oauthData.userName) {
if (!_adal._getItem(_adal.CONSTANTS.STORAGE.FAILED_RENEW)) {
// Idtoken is expired or not present
_adal.acquireToken(_adal.config.loginResource, function (error, tokenOut) {
if (error) {
$rootScope.$broadcast('adal:loginFailure', 'auto renew failure');
} else {
if (tokenOut) {
_oauthData.isAuthenticated = true;
}
}
});
}
}
}
$timeout(function () {
updateDataFromCache(_adal.config.loginResource);
$rootScope.userInfo = _oauthData;
}, 1);
}
...
And here is a sample code which could save the tokens into cache for your reference:
<html>
<head>
<script src="https://unpkg.com/vue"></script>
<script src="node_modules\adal-angular\lib\adal.js"> </script>
<script src="config.js"> </script>
</head>
<body>
<div>
<button onclick="login()" >Login</button>
</div>
<script>
var authContext=new AuthenticationContext(config);
function login(){
authContext.login();
}
function init(configOptions){
if (configOptions) {
// redirect and logout_redirect are set to current location by default
var existingHash = window.location.hash;
var pathDefault = window.location.href;
if (existingHash) {
pathDefault = pathDefault.replace(existingHash, '');
}
configOptions.redirectUri = configOptions.redirectUri || pathDefault;
configOptions.postLogoutRedirectUri = configOptions.postLogoutRedirectUri || pathDefault;
// create instance with given config
} else {
throw new Error('You must set configOptions, when calling init');
}
// loginresource is used to set authenticated status
updateDataFromCache(authContext.config.loginResource);
}
var _oauthData = { isAuthenticated: false, userName: '', loginError: '', profile: '' };
var updateDataFromCache = function (resource) {
// only cache lookup here to not interrupt with events
var token = authContext.getCachedToken(resource);
_oauthData.isAuthenticated = token !== null && token.length > 0;
var user = authContext.getCachedUser() || { userName: '' };
_oauthData.userName = user.userName;
_oauthData.profile = user.profile;
_oauthData.loginError = authContext.getLoginError();
};
init(config);
function saveTokenFromHash(){
var hash = window.location.hash;
var requestInfo = authContext.getRequestInfo(hash);
if (authContext.isCallback(hash)) {
// callback can come from login or iframe request
var requestInfo = authContext.getRequestInfo(hash);
authContext.saveTokenFromHash(requestInfo);
window.location.hash = '';
if (requestInfo.requestType !== authContext.REQUEST_TYPE.LOGIN) {
authContext.callback = window.parent.AuthenticationContext().callback;
}
}
}
saveTokenFromHash();
</script>
</body>
</html>

Wit.ai Clear or Reset context

How can I reset or clear the context at the end of my story or when the user wants to restart the process ? I already have a reset function of my own ... Not very effective ! Can you please explain me what I have to do ? Thank you very much
reset({sessionId,context}) {
return new Promise(function(resolve, reject) {
context = null;
return resolve(context);
});
}
And for the session, I do that :
var findOrCreateSession = (fbid) => {
let sessionId;
Object.keys(sessions).forEach(k => {
if (sessions[k].fbid === fbid) {
sessionId = k;
}
});
if (!sessionId) {
console.log("je cree une session car yen a pas");
sessionId = new Date().toISOString();
sessions[sessionId] = {
fbid: fbid,
context: {}
};
}
return sessionId;
};
How can I kill the session at the end of the story and/or kill context and reset the process please !
You could potentially delete the old session and create a new one before the webhook hits the Wit.ai controller.
See the code below for an example:
Webhook POST handler
// Conversation History
let sessionId = WitRequest.getSession(senderId);
if (message.text.toLowerCase() == "break") {
// New Conversation History
// Delete the old session
WitRequest.deleteSession(sessionId);
// Get new Session Id
sessionId = WitRequest.getSession(senderId);
}
let sessionData = WitRequest.getSessionData(sessionId);
wit.runActions(
sessionId,
message.text,
sessionData
)
.then((context) => {
sessionData = context;
})
.catch((error) => {
console.log("Error: " + error);
});
WitRequest Class
static getSession(senderId) {
let sessionId = null;
for (let currentSessionId in sessions) {
if (sessions.hasOwnProperty(currentSessionId)) {
if (sessions[currentSessionId].senderId == senderId) {
sessionId = currentSessionId
}
}
}
if (!sessionId) {
sessionId = new Date().toISOString();
sessions[sessionId] = {
senderId: senderId,
context: {}
}
}
return sessionId;
}
static getSessionData(sessionId) {
return sessions[sessionId].context;
}
static deleteSession(sessionId) {
delete sessions[sessionId];
}
static clearSession(session) {
session.context = {};
}

Parse.com: query.each executes in parrallel, reaches limit

I am running a batch job and I would like them to be run serially for each query result
The problem is that it seems that query.each executes everything in parrallel
How can I change my code to have everything execute serially?
Parse.Cloud.job("fetchMenus", function(request, status) {
var counter = 0;
// Query for all users
var LocationSP = Parse.Object.extend("Location");
var query = new Parse.Query(LocationSP);
query.doesNotExist("menu");
query.equalTo("city_lc","new york");
// query.limit(10);
var p = Parse.Promise.as("");
query.each(function(location) {
p = p.then(function(){
if (counter % 100 === 0) {
// Set the job's progress status
status.message(counter + " users processed.");
}
// console.log(location);
// console.log(location.get("location_id"));
Parse.Cloud.run('getMenu2', {alias: location.get("location_id") }, {
success: function(result) {
// result is 'Hello world!'
counter += 1;
return Parse.Promise.as("1");
},
error: function(error) {
return Parse.Promise.as("1");
}
});
})
return p;
}).then(function() {
// Set the job's success status
status.success("Migration completed successfully.");
}, function(error) {
// Set the job's error status
status.error("Uh oh, something went wrong." + error);
});
});
Both query.each and Parse.Cloud.run return a promise, so you can simply write as following:
Parse.Cloud.job("fetchMenus", function(request, status) {
var LocationSP, counter, query;
counter = 0;
LocationSP = Parse.Object.extend("Location");
query = new Parse.Query(LocationSP);
query.doesNotExist("menu");
query.equalTo("city_lc", "new york");
return query.each(function(location) {
if (counter % 100 === 0) {
status.message(counter + " users processed.");
}
return Parse.Cloud.run('getMenu2', {
alias: location.get("location_id")
}).then(function(result) {
counter += 1;
return Parse.Promise.as("1");
}, function(error) {
return Parse.Promise.as("1");
});
}).then(function() {
return status.success("Migration completed successfully.");
}, function(error) {
return status.error("Uh oh, something went wrong." + error);
});
});