Strange behavior when updating entity FK in LightSwitch app - javascript

I have three entities: selected_spo, selected_product, selected_stock.
I need to update a FK in the existing entity selected_stock in order to link it to the newly created entity new_spoxs.
new_spoxs has mandatory FKs with entities selected_spo and selected_product
If I call myapp.applyChanges() immediately after I do the assignments then the whole update process enters in a very strange state.
The newly created entity new_spoxs is saved to DB but the FK selected_stock.supplier_po_x_stocks is not created.
There is no error in the [Function onError] of the Promise myapp.applyChanges().then... The UI keeps telling me that there are Unsaved Changes but Save changes button has no effect.
I also tried to solve this in more steps.
First create the new entity, do a myapp.applyChanges(), update the FK link selected_stock.supplier_po_x_stocks = new_spoxs; and then do another final myapp.applyChanges().
This was also NOT successful without that delay.
It ONLY works if I use a delay as you can see in the code !
This is totally not OK.
Where I am wrong ?
Or maybe this is a bug in LightSwitch ?!
var p_spo = myapp.activeDataWorkspace.storeData.supplier_poes_SingleOrDefault(id_spo_selected);
var p_product = myapp.activeDataWorkspace.storeData.products_SingleOrDefault(id_product_selected);
var p_stock = myapp.activeDataWorkspace.storeData.stocks_SingleOrDefault(id_stock_selected);
var promises_to_execute = [p_spo, p_product, p_stock];
var promises_executor = promises_to_execute.map(function (_p) {
return _p.execute();
});
WinJS.Promise.join(promises_executor).then(function (promises_result) {
var selected_spo = promises_result[0].results[0];
var selected_product = promises_result[1].results[0];
var selected_stock = promises_result[2].results[0];
//Next create a new supplier_po_x_stocks entity
//var new_spoxs = new myapp.supplier_po_x_stock();
var new_spoxs = myapp.activeDataWorkspace.storeData.supplier_po_x_stocks.addNew();
new_spoxs.product = selected_product;
new_spoxs.supplier_po = selected_spo;
new_spoxs.qty_requested = qty_to_be_ordered;
new_spoxs.qty_entered = 0;
//This is not working without WinJS.Promise.timeout(1000) ... !!! NOT OK !!!
selected_stock.supplier_po_x_stocks = new_spoxs;
WinJS.Promise.timeout(1000).then(function () {
myapp.applyChanges().then(
function () {
screen.v_spo_products_to_be_ordereds.refresh();
msls.showMessageBox('Save ok');
},
function (err) {
msls.showMessageBox(JSON.stringify(err, null, 4));
});
});
}, function (err) {
msls.showMessageBox(JSON.stringify(err, null, 4));
});

Related

Dynamically Update List/List Items

(Small edit: "ce" is a shortcut for "React.createElement")
I have been working on a React/WebSockets/AJAX project for a chat room/message board. I am quite new to React, and I have caught on to most of it but I am having trouble with dynamically updating a list/refreshing its items.
What I want to do is every time my WebSocket receives an "update" message, I want to update the lists with the latest messages. The issue I am having is that they are not displaying anything, even though my update method is being called properly. I am getting no errors.
In my UserPageComponent, I have:
constructor(props) {
super(props);
this.state = {
channelType: "global",
messageToSend: "",
target: "",
globalMessages: [],
privateMessages: []
};
}
In my UserPageComponent render I have this:
... return 'Global Chat: ',
ce('ul', {id: "globalMessageDiv"}, this.state.globalMessages),
'Private Chat: ',
ce('ul', {id: "privateMessageDiv"}, this.state.privateMessages),
...
Here is my update (called every time a new message is sent - keep in mind globalMsgs/privateMsgs is populated properly with ALL messages sent as of when it was called).
updateData() {
const globalMsgs = this.getMessages("global");
const privateMsgs = this.getMessages("private");
var compiledGms = [];
var compiledPms = [];
globalMsgs.map((gm) => {
var gmToLi = ce('li', gm);
compiledGms.push(gmToLi);
});
privateMsgs.map((pm) => {
var pmToLi = ce('li', pm);
compiledPms.push(pmToLi);
});
this.setState({globalMessages: compiledGms});
this.setState({privateMessages: compiledPms});
}
The update function is called whenever I send a message and works like needed. (example below)
I'm unsure what else I can provide, however here is an example of what "globalMsgs" holds: data in globalMsgs/privateMsgs variables example
Try this below code
updateData() {
const globalMsgs = this.getMessages("global");
const privateMsgs = this.getMessages("private");
var compiledGms = [];
var compiledPms = [];
for(var i=0;i<globalMsgs.length;i++){
var gmToLi = ce('li', globalMsgs[i]);
compiledGms.push(gmToLi);
if(i==globalMsgs.length-1){
this.setState({globalMessages: compiledGms});
}
}
for(var i=0;i<privateMsgs.length;i++){
var pmToLi = ce('li', privateMsgs[i]);
compiledPms.push(pmToLi);
if(i==privateMsgs.length-1){
this.setState({privateMessages: compiledPms});
}
}
}

Delete an entry from firebase realtime database with a click of a button

I need help on how to remove a firebase entry
I have the following code in the javascript:
document.getElementById('deleteDriver_btn').onclick = function() {
firebase.database().ref('drivers').child('driver_num').on('value', function(driverSnapshot) {
var driverChildSnapshot = driverSnapshot.val();
var queryRef = firebase.database().ref('drivers').orderByChild('driver_num').equalTo(dataRow);
queryRef.remove();
});
};
I get an error saying that queryRef.remove() is not a function.
Firebase entry goes like:
---driver
--AKSJDIWDKSADKAWsdak <---- want to delete this and the data underneath
-driver_num
-first_name
-last_name
--akdjwoajdksafksndjiw <---- want to retain this
-driver_num
-first_name
-last_name
Okay I found my answer thanks to the hint #TommyBs sent about the references. I just query to extract the key and then initiate .ref().remove()
document.getElementById('deleteDriver_btn').onclick = function() {
var refe = firebase.database().ref("drivers");
var diskey = "";
refe.orderByChild("driver_num").equalTo(dataRow).on("child_added", function(snapshots)
{
diskey = snapshots.key;
});
firebase.database().ref("drivers/" + diskey).remove();
};

Unable to update table in Advanced Data Persistence mode

I have an issue related to database. I am currently working with Gupshup bot programming. There are two different data persistence modes which can be read here and here. In the advanced data persistence, the following code is documented to put data into data base:
function MessageHandler(context, event) {
if(event.message=='update bug - 1452') {
jiraUpdate(context);
}
}
function jiraUpdate(context){
//connect to Jira and check for latest update and values
if(true){
context.simpledb.doPut("1452" ,"{\"status\":\"QA pending\",\"lastUpdated\":\"06\/05\/2016\",\"userName\":\"John\",\"comment\":\"Dependent on builds team to provide right build\"}");
} else{
context.sendResponse('No new updates');
}
}
function DbPutHandler(context, event) {
context.sendResponse("New update in the bug, type in the bug id to see the update");
}
If I want to change only one of column (say status or last Updated) in the table for the row with key value 1452, I am unable to do that. How can that be done?
I used the following code:
function MessageHandler(context, event) {
// var nlpToken = "xxxxxxxxxxxxxxxxxxxxxxx";//Your API.ai token
// context.sendResponse(JSON.stringify(event));
if(event.message=='deposit') {
context.sendResponse("Enter the amount to be deposited");
}
if(event.message=="1000") {
jiraUpdate(context);
}
if(event.message== "show"){
context.simpledb.doGet("1452");
}
}
function HttpResponseHandler(context, event) {
var dateJson = JSON.parse(event.getresp);
var date = dateJson.date;
context.sendResponse("Today's date is : "+date+":-)");
}
function jiraUpdate(context){
//connect to Jira and check for latest update and values
if(true){
context.simpledb.doPut("aaa" ,"{\"account_number\":\"90400\",\"balance\":\"5800\"}");
} else{
context.sendResponse('No new updates');
}
}
/** Functions declared below are required **/
function EventHandler(context, event) {
if (!context.simpledb.botleveldata.numinstance)
context.simpledb.botleveldata.numinstance = 0;
numinstances = parseInt(context.simpledb.botleveldata.numinstance) + 1;
context.simpledb.botleveldata.numinstance = numinstances;
context.sendResponse("Thanks for adding me. You are:" + numinstances);
}
function DbGetHandler(context, event) {
var bugObj = JSON.parse(event.dbval);
var bal = bugObj.balance;
var acc = bugObj.account_number;
context.sendResponse(bal);
var a = parseInt (bal,10);
var b = a +1000;
var num = b.toString();
context.simpledb.doPut.aaa.balance = num;
}
function DbPutHandler(context, event) {
context.sendResponse("testdbput keyword was last put by:" + event.dbval);
}
Since the hosted DB that is provided by Gupshup is the DynamoDB of AWS. Hence you can enter something as a key, value pair.
Hence you will have to set the right key while using doPut method to store data into the database and use the same key to get the data from the database using the doGet method.
To update the data you should first call doGet method and then update the JSON with right data and then call doPut method to update the database with the latest data.
I have also added something which is not present in the documentation, You can now make DB calls and choose which function the response goes to.
I am refactoring your example as using 3 keywords and hard coding few things just for example -
have - this will update the database with these values
{"account_number":"90400","balance":"5800"}
deposit - on this, the code will add 1000 to the balance
show - on this, the code show the balance to the user.
Code -
function MessageHandler(context, event) {
if(event.message=='have') {
var data = {"account_number":"90400","balance":"5800"};
context.simpledb.doPut(event.sender,JSON.stringify(data),insertData); //using event.sender to keep the key unique
return;
}
if(event.message=="deposit") {
context.simpledb.doGet(event.sender, updateData);
return;
}
if(event.message== "show"){
context.simpledb.doGet(event.sender);
return;
}
}
function insertData(context){
context.sendResponse("I have your data now. To update just say \"deposit\"");
}
function updateData(context,event){
var bugObj = JSON.parse(event.dbval);
var bal = bugObj.balance;
var a = parseInt(bal,10);
var b = a + 1000;
var num = b.toString();
bugObj.balance = num;
context.simpledb.doPut(event.sender,bugObj);
}
function EventHandler(context, event) {
if (!context.simpledb.botleveldata.numinstance)
context.simpledb.botleveldata.numinstance = 0;
numinstances = parseInt(context.simpledb.botleveldata.numinstance) + 1;
context.simpledb.botleveldata.numinstance = numinstances;
context.sendResponse("Thanks for adding me. You are:" + numinstances);
}
function DbGetHandler(context, event) {
var accountObj = JSON.parse(event.dbval);
context.sendResponse(accountObj);
}
function DbPutHandler(context, event) {
context.sendResponse("I have updated your data. Just say \"show\" to view the data.");
}

Assign mongoose return result to node js variable

I am new to node js and mongoose.I have the below code in node js. I wanted to assign the return userData record by the mongoose to variable user which is outside the callback.
var user = null;
User.findOne({$and: [{"_id": advisorId}, {"role": "advisor"}]}, {firstName:1,lastName:1, '_id':0},
function(err,userData) {
user = userData;
});
Once I have the return result in user variable I can directly pass it to the jade view as follow:
TrackSession.find({'advisor_id' : advisorId},fields,function(err, chatHistoryData) {
var jade = require('jade');
var html = jade.renderFile(appRoot+'/views/generatePDFHTML.jade', {'chatHistoryData': chatHistoryData,
'selectedOptions':selectedOptions,
'advisor':user,
'tableHeaders':tableHeaders
});
console.log(html); return false;
});
But when I am trying to do this I am getting null as the value of the user variable. Is there any specific solution to achieve this?
The callback of the findOne() is asynchronous, it gets executed after you get to rendering the jade. The execution jumps to "TrackSession" before the user variable gets a new value.
You should put the var html = ... inside the callback.
var user = null;
User.findOne({$and: [{"_id": advisorId}, {"role": "advisor"}]},{firstName:1,lastName:1, '_id':0}, function(err,userData,user) {
user = userData;
TrackSession.find({'advisor_id' : advisorId},fields,function(err, chatHistoryData) {
var jade = require('jade');
var html = jade.renderFile(appRoot+'/views/generatePDFHTML.jade', {'chatHistoryData': chatHistoryData,
'selectedOptions':selectedOptions,
'advisor':user,
'tableHeaders':tableHeaders
});
console.log(html); return false;
});
});

CRM Javascript Automatically Populated a Look-up Value with a specific field

I'm trying to write a javascript on CRM Phone Call page. We have a custom look-up field called new_department, and we want to automatically populate the field with value "IT" (there should be one) when the form is opened.
The thing is we have a separate Dev and Production CRM link therefore I cannot just assign a hard-coded GUID value into this field. So first I wrote a Rest Retrieve Multiple to get the correct department.
Then my problem is I'm not sure about the result returned from this Retrieve Multiple. How do I grab just the GUID from Rest? I'm seeing that this is a type of {Object}. Then lastly how do I go about setting the lookup value after retrieving the {Object}? Any help is greatly appreciated.
Here is my code.
function phonecall() {
var formType = Xrm.Page.ui.getFormType();
if (formType == 1) //create
{
//RetrieveMultiple function
var DepartmentId = getITDepartment();
//set the lookup value
var ID = DepartmentId.id;
var departmentValue = new Array();
departmentValue[0] = new Object();
departmentValue[0].id = DepartmentId;
departmentValue[0].name = 'IT';
userValue[0].entityType = "new_department";
Xrm.Page.getAttribute("new_department").setValue(departmentValue);
}
}
function getITDepartment()
{
XrmServiceToolkit.Rest.RetrieveMultiple("new_departmentSet", "$select=new_departmentId&$filter=new_name eq 'IT'",
function (results) {
if (results.length > 0)
resultList = results;
}, function (error) { alert(error); }, function onComplete() { }, false);
return resultList;
}
Thanks much.
I'm not familiar with XrmServiceToolkit but here how code could look like to work properly - I replaced only assigning part:
var DepartmentId = getITDepartment();
if (DepartmentId != null && DepartmentId.length > 0){
Xrm.Page.getAttribute("new_department").setValue([{
id: DepartmentId[0].new_departmentId,
name: "IT",
entityType: "new_department"
}]);
}
You are setting the lookup value correctly, you just need to get the Id correctly. The results variable is an array of new_department records, so try something like this:
var resultId = null;
XrmServiceToolkit.Rest.RetrieveMultiple("new_departmentSet", "$select=new_departmentId&$filter=new_name eq 'IT'",
function (results) {
if (results.length > 0)
resultId = results[0].new_departmentId; //gets the first record's Id
}, function (error) { alert(error); }, function onComplete() { }, false);
return resultId;

Categories