Updating a specific record in the database? - javascript

I'm using Javascript with applab. The code creates new users fine, but it only updates the first record. Any ideas how to fix this so that it will update for each new and returning user? I think I need to use a math function with "mostRecentID" or "record.ID" to achieve this.
Link to Project: https://studio.code.org/projects/applab/bSkJw2auZx8Iq7ZGemsT7HwQrOVBWFPl6eLl0R0a6VU If you go to "how it works (view code)", and then you can see the code and the database.
//The database for this code already exists.
//This code creates new users fine, but it only updates the first record.
//What code will update a specific ID in the database
//I think I need to use a math function with "mostRecentID" or "record.ID" to achieve this.
var mostRecentID=1;
var player = {};
var UserID = getUserId();
onEvent("addNewRecordButton", "click", function() {
readRecords("AllUserData", player, function(records) {
var count = records.length;
if (count > 1) {
} else if ((count == 1)) {
} else {
var player = {};
player.UserID = getUserId();
player.Username=getText("usernameInput");
createRecord("AllUserData", player, function(record) {
mostRecentID=record.id;
});
}
});
});
onEvent("updateInformationButton", "click", function() {
updateRecord("AllUserData", {id:mostRecentID,UserID:getUserId(),Username:(getText("usernameInput"))}, function() {
});
});

Let's say you wanted to update a record matching the current user's user ID. You would need to specify the user ID in the parameters object.
readRecords("AllUserData", {UserID: getUserId()}, function (records) {
if (records.length > 0) {
updateRecord("AllUserData", {id: records[0].id, UserID:getUserId(),Username:(getText("usernameInput"))}, function () {
// callback code
});
} else {
createRecord("AllUserData", {UserID:getUserId(),Username:(getText("usernameInput"))}, function () {
// callback code
});
}
});

Related

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.");
}

Comparing input value with value of an array in AngularJS

I have a problem with the validation about existing values. I don't know how to compare two values and add the new value only, when it isn't exist in the Database. I've tried with angular.forEach() but it adds the new object always when the compare (what I'm doing with angular.equals()) isn't false and thats wrong. The object have to be only one time in the database.
Here is my create function:
$scope.createItem = function (createItem) {
//here I have to define a query to compare createItem.lname with the table list (array items from the db) in the view.
//That was the code:
angular.forEach(nameslist, function (value) {
if (angular.equals(createItem.lname, value.lname)) {
CrudService.create(createItem).then(
function () {
//success code
$scope.createItem = null;
},
function (err) {
//error code
});
}
}
});
}
Can anyone give me some help.. I don't know how to solve it.
var itemAbsent = namelist.map(function(value){
return value.name;
}).indexOf(createItem.name) < 0;
if (nameAbsent){
CrudService.create(createItem).then(
function () {
//success code
$scope.createItem = null;
},
function (err) {
//error code
});
}
}

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;

I want to load local store in between the server response (making java script code synchronysed)

I have view page where am trying to display all organizations,which is
obtained by a server call..In order to feel the application responsive
, in between the server response I want to load all local store
items.. But server call is always executing first.. The code I
mentioned bellow..
initialize: function()
{
var me = this,
st = Ext.create("Ext.data.Store", {
fields : [ {......................}]});
me.callParent(arguments);
me.setStore(st);
me.on({
show : me.onShow,
scope: me
});
},
onShow:function()
{
var me = this;
Ext.create('Ext.util.DelayedTask',
//call back function ,purpose : delayed exicution
function () {
me.DelShow(function(){
_syncMgr.getOrgGroup(-1,0,5); // servercall
});
}).delay(500);
},
DelShow: function(callback)
{
orgStore = Ext.getStore('Organizations'),
orgStore.load(function(records)
{
var i=0,len = records.length,
for(;i<len;i++)
{
organization = records[i];
regId = organization.get('rg_id');
resStr = organization.Resources();
resStr.load({callback:function(resorces)
{
var i = 0,rlen =resorces.length,
obj = {},
obj.rg_id = str.boundTo.get('rg_id');
}
orgViStr.add([obj]);
});
}
});
me.lodorg(callback);
},
lodorg:function(callback)
{
callback();
console.log("I don't know why this call back works first....");
console.log("plz help me to work last....");
}
Call You callback method after You load data from local store .
What you want to do is add the content from your local store to the list that is currently set in the view then refresh the list.
var localStore = something.getStore(),
entries = [];
localStore.each(function(entry){
entries.push(entry.copy);
});
//me is the list that is set in the view
me.add(entries);
me.deselectAll();
me.refresh();
Hope that helps :)

Angularjs must refresh page to see changes

What I have is simple CRUD operation. Items are listed on page, when user clicks button add, modal pops up, user enters data, and data is saved and should automatically (without refresh)be added to the list on page.
Service:
getAllIncluding: function(controllerAction, including) {
var query = breeze.EntityQuery.from(controllerAction).expand(including);
return manager.executeQuery(query).fail(getFailed);
},
addExerciseAndCategories: function(data, initialValues) {
var addedExercise = manager.createEntity("Exercise", initialValues);
_.forEach(data, function(item) {
manager.createEntity("ExerciseAndCategory", { ExerciseId: addedExercise._backingStore.ExerciseId, CategoryId: item.CategoryId });
});
saveChanges().fail(addFailed);
function addFailed() {
removeItem(items, item);
}
},
Controller:
$scope.getAllExercisesAndCategories = function() {
adminCrudService.getAllIncluding("ExercisesAndCategories", "Exercise,ExerciseCategory")
.then(querySucceeded)
.fail(queryFailed);
};
function querySucceeded(data) {
$scope.queryItems = adminCrudService.querySucceeded(data);
var exerciseIds = _($scope.queryItems).pluck('ExerciseId').uniq().valueOf();
$scope.exerciseAndCategories = [];
var createItem = function (id, exercise) {
return {
ExerciseId: id,
Exercise : exercise,
ExerciseCategories: []
};
};
// cycle through ids
_.forEach(exerciseIds, function (id) {
// get all the queryItems that match
var temp = _.where($scope.queryItems, {
'ExerciseId': id
});
// go to the next if nothing was found.
if (!temp.length) return;
// create a new (clean) item
var newItem = createItem(temp[0].ExerciseId, temp[0].Exercise);
// loop through the queryItems that matched
_.forEach(temp, function (i) {
// if the category has not been added , add it.
if (_.indexOf(newItem.ExerciseCategories, i.ExerciseCategory) < 0) {
newItem.ExerciseCategories.push(i.ExerciseCategory);
}
});
// Add the item to the collection
$scope.items.push(newItem);
});
$scope.$apply();
}
Here is how I add new data from controller:
adminCrudService.addExerciseAndCategories($scope.selectedCategories, { Name: $scope.NewName, Description: $scope.NewDesc });
So my question is, why list isn't updated in real time (when I hit save I must refresh page).
EDIT
Here is my querySuceeded
querySucceeded: function (data) {
items = [];
data.results.forEach(function(item) {
items.push(item);
});
return items;
}
EDIT 2
I believe I've narrowed my problem !
So PW Kad lost two hours with me trying to help me to fix this thing (ad I thank him very very very much for that), but unfortunately with no success. We mostly tried to fix my service, so when I returned to my PC, I've again tried to fix it. I believe my service is fine. (I've made some changes as Kad suggested in his answer).
I believe problem is in controller, I've logged $scope.items, and when I add new item they don't change, after that I've logged $scope.queryItems, and I've noticed that they change after adding new item (without refresh ofc.). So probably problem will be solved by somehow $watching $scope.queryItems after loading initial data, but at the moment I'm not quite sure how to do this.
Alright, I am going to post an answer that should guide you on how to tackle your issue. The issue does not appear to be with Breeze, nor with Angular, but the manner in which you have married the two up. I say this because it is important to understand what you are doing in order to understand the debug process.
Creating an entity adds it to the cache with an entityState of isAdded - that is a true statement, don't think otherwise.
Now for your code...
You don't have to chain your query execution with a promise, but in your case you are returning the data to your controller, and then passing it right back into some function in your service, which wasn't listed in your question. I added a function to replicate what yours probably looks like.
getAllIncluding: function(controllerAction, including) {
var query = breeze.EntityQuery.from(controllerAction).expand(including);
return manager.executeQuery(query).then(querySucceeded).fail(getFailed);
function querySucceeded(data) {
return data.results;
}
},
Now in your controller simply handle the results -
$scope.getAllExercisesAndCategories = function() {
adminCrudService.getAllIncluding("ExercisesAndCategories", "Exercise,ExerciseCategory")
.then(querySucceeded)
.fail(queryFailed);
};
function querySucceeded(data) {
// Set your object directly to the data.results, because that is what we are returning from the service
$scope.queryItems = data;
$scope.exerciseAndCategories = [];
Last, let's add the properties we create the entity and see if that gives Angular a chance to bind up properly -
_.forEach(data, function(item) {
var e = manager.createEntity("ExerciseAndCategory");
e.Exercise = addedExercise; e.Category: item.Category;
});
So I've managed to solve my problem ! Not sure if this is right solution but it works now.
I've moved everything to my service, which now looks like this:
function addCategoriesToExercise(tempdata) {
var dataToReturn = [];
var exerciseIds = _(tempdata).pluck('ExerciseId').uniq().valueOf();
var createItem = function (id, exercise) {
return {
ExerciseId: id,
Exercise: exercise,
ExerciseCategories: []
};
};
// cycle through ids
_.forEach(exerciseIds, function (id) {
// get all the queryItems that match
var temp = _.where(tempdata, {
'ExerciseId': id
});
// go to the next if nothing was found.
if (!temp.length) return;
// create a new (clean) item
var newItem = createItem(temp[0].ExerciseId, temp[0].Exercise);
// loop through the queryItems that matched
_.forEach(temp, function (i) {
// if the category has not been added , add it.
if (_.indexOf(newItem.ExerciseCategories, i.ExerciseCategory) < 0) {
newItem.ExerciseCategories.push(i.ExerciseCategory);
}
});
// Add the item to the collection
dataToReturn.push(newItem);
});
return dataToReturn;
}
addExerciseAndCategories: function (data, initialValues) {
newItems = [];
var addedExercise = manager.createEntity("Exercise", initialValues);
_.forEach(data, function (item) {
var entity = manager.createEntity("ExerciseAndCategory", { ExerciseId: addedExercise._backingStore.ExerciseId, CategoryId: item.CategoryId });
items.push(entity);
newItems.push(entity);
});
saveChanges().fail(addFailed);
var itemsToAdd = addCategoriesToExercise(newItems);
_.forEach(itemsToAdd, function (item) {
exerciseAndCategories.push(item);
});
function addFailed() {
removeItem(items, item);
}
}
getAllExercisesAndCategories: function () {
var query = breeze.EntityQuery.from("ExercisesAndCategories").expand("Exercise,ExerciseCategory");
return manager.executeQuery(query).then(getSuceeded).fail(getFailed);
},
function getSuceeded(data) {
items = [];
data.results.forEach(function (item) {
items.push(item);
});
exerciseAndCategories = addCategoriesToExercise(items);
return exerciseAndCategories;
}
And in controller I have only this:
$scope.getAllExercisesAndCategories = function () {
adminExerciseService.getAllExercisesAndCategories()
.then(querySucceeded)
.fail(queryFailed);
};
function querySucceeded(data) {
$scope.items = data;
$scope.$apply();
}

Categories