breeze doesn't recognize the modified entity - javascript

I have a breeze implementation where it takes a location object and displays the properties on the UI. I do a change to a few properties and try to save the changes, but breeze doesn't recognized the entity as changed. Following is my code:
[HttpGet]
[CustomAuthorize(Claims = "permission:CanViewLocationAttributes")]
public Location GetLocationById(int clientId, int locationId)
{
//returns a single Location object
}
Following is my client-side functionality to retrieve the entity and save the entity:
function getLocationById(clientId, locationId) {
var self = this;
return EntityQuery.from('GetLocationById')
.withParameters({ clientId: clientId, locationId : locationId })
.using(self.manager)
.execute()
.then(querySucceeded, this._queryFailed);
function querySucceeded(data) {
if (data.results.length > 0) {
return data.results[0];
}
logSuccess(localize.getLocalizedString('_RetrievedLocations_'), locations, true);
}
}
function saveLocationSettings(clientId) {
var self = this;
var saveOptions = this.manager.saveOptions.using({ resourceName: "SaveLocationSettings", allowConcurrentSaves: true });
var entitiesToSave = self.manager.getChanges();
return self.manager.saveChanges(entitiesToSave, saveOptions).then(saveSucceeded, saveFailed);
}
my problem is that here the value of entitiesToSave is 0, even after I make changes to the fields in UI and save them.
Following is how I bind the entity to my angular model:
function getLocationDetails() {
clientcontext.location.getLocationById($route.current.params.clientId, $route.current.params.id)
.then(function (data) {
basicLocationSettings.id = data.locationId;
basicLocationSettings.parent = data.fkParentLocationId;
basicLocationSettings.locationType = data.locationType;
basicLocationSettings.locationName = data.locationName;
basicLocationSettings.locationDisplayName = data.locationDisplayName;
basicLocationSettings.locationCode = data.locationCode;
basicLocationSettings.isActive = data.activeStatus;
basicLocationSettings.timeZone = data.fkTimeZoneId;
basicLocationSettings.usesAppointments = data.usesAppointments;
basicLocationSettings.availabilityWindowDays = data.availabilityWindowDays;
basicLocationSettings.appointmentCutOffDays = data.appointmentCutOffDays;
basicLocationSettings.dailySummaryEmailTime = data.dailySummaryEmailTime;
basicLocationSettings.reminderBeforeApptEmailTime = data.reminderBeforeApptEmailTime;
basicLocationSettings.saveLocationSettings = function () {
clientcontext.location.saveLocationSettings($route.current.params.clientId);
}
});
}
Can anyone explain what I'm doing wrong? This is my first attempt on breeze and I'm kind of stuck here.

It looks like you are copying the breeze location entity's property values into an pojo object variable named "basicLocationSettings". Any changes to basicLocationSettings will not be tracked by the breeze entity manager or reflected in the source breeze entity. You'll need to bind the actual breeze entity to your UI so that user data entry modifies the entity property values directly.

I modified my code as follows and now the save is working:
function getLocationById(clientId, locationId) {
var self = this;
var location = null;
return EntityQuery.from('GetLocationById')
.withParameters({ clientId: clientId, locationId : locationId })
.using(self.manager)
.execute()
.then(querySucceeded, this._queryFailed);
function querySucceeded(data) {
if (data.results.length > 0) {
location = data.results[0];
}
logSuccess(localize.getLocalizedString('_RetrievedLocations_'), locations, true);
return location;
}
}
Note that I'm returning a location object, and in my controller, I bind the location object to my POJO.
function getLocationDetails() {
clientcontext.location.getLocationById($route.current.params.clientId, $route.current.params.id)
.then(function (data) {
basicLocationSettings.location = data;
basicLocationSettings.saveLocationSettings = saveLocationSettings;
});
}
Now when I call saveChanges(), I pass the location object to the repository:
function saveLocationSettings() {
clientcontext.location.saveLocationSettings(basicLocationSettings.location);
}

Related

JSON data not being saved in WebAPI

I'm following a Pluralsight course on AngularJS and WebAPI together. I'm trying to save data being sent from the client to the server using PUT, but the data is not saving and I'm not getting any errors. Also, It doesn't event hit the correct server side code because the breakpoints are not being caught. I've tried to change the type of HTTP method, but I need this one. The only thing being sent back is a "204: No Content" code from the server.
This is how the PUT and POST methods look like. Breakpoints in any of these methods will not be captured.
// POST: api/Products
public void Post([FromBody]Product product) // Creating a product
{
var productRepository = new ProductRepository();
var newProduct = productRepository.Save(product);
}
// PUT: api/Products/5
public void Put(int id, [FromBody]Product product) // Updating a product
{
var productRepository = new ProductRepository();
var updatedProduct = productRepository.Save(id, product);
}
ProductRepository looks like this:
internal Product Save(Product product)
{
// Read in the existing products
var products = this.Retrieve();
// Assign a new Id
var maxId = products.Max(p => p.ProductID);
product.ProductID = maxId + 1;
products.Add(product);
WriteData(products);
return product;
}
internal Product Save(int id, Product product)
{
// Read in the existing products
var products = this.Retrieve();
// Locate and replace the item
var itemIndex = products.FindIndex(p => p.ProductID == product.ProductID);
if (itemIndex > 0)
{
products[itemIndex] = product;
}
else
{
return null;
}
WriteData(products);
return product;
}
This is the main part of the controller that is being used (using Controller-As syntax:
var vm = this;
vm.submit = function () {
vm.message = "";
if (vm.product.productID) {
vm.product.$update({ id: vm.product.productID }, function (data {
console.log(data);
vm.message = "Save Complete";
});
} else {
vm.product.$save(function (data) {
vm.originalProduct = angular.copy(data);
vm.message = "Save Complete";
});
}
};
Finally, productResource is a custom service that looks like this:
var productResource = function($resource, appSettings) {
return $resource(appSettings.serverPath + "/api/Products/:id", null, {
'update': { method: 'PUT' }
});
}
I've tried to look to see if it's a CORS problem, but it's not since I have it enabled at the class level.
Please check your API if it implements CORS(Cross Origin Resource Sharing)
Shouldn't
var itemIndex = products.FindIndex(p => p.ProductID == product.ProductID);
be
var itemIndex = products.FindIndex(p => p.ProductID == id);

how to store array value in angularjs and then redirect

$scope.messagearray = {};
$scope.messagewant = function(info) {
$scope.messagearray = info;
$location.path("/messagewant");
}
my code is redirecting without storing value in array
The code can be modified like this. Now info is passed to new location via query parameters.
$scope.messagearray = {};
$scope.messagewant = function(info) {
$scope.messagearray = info;
$location.path("/messagewant?info="+info);
}

How to access $scope object in factory using AngularJS?

I have serialize method for post , So riskAssessmentKey is not part of $scope.topRiskDTO but i pass the riskAssessmentKey value from $scope.riskAssessmentDTO.riskAssessmentkey and now i am posting to factory but when i save all values are posting but riskAssessmentKey is coming undefined i dont know why..
So far tried code....
parentCtrl.js
$scope.addTopRisk = function(){
topRiskGridConfig.topRiskmodalWinConfig.title = 'Add top Risk';
$scope.viewTopRiskWin.setOptions(topRiskGridConfig.topRiskmodalWinConfig);
$scope.$broadcast('addTopRisk',$scope.riskAssessmentDTO.riskAssessmentKey);
};
childCtrl.js
$scope.topRiskDTO = {};
$scope.issuePltDataSource = kendoCustomDataSource.getDropDownDataSource('RA_KY_CNCRN_IS_PLTFM');
$scope.$on('addTopRisk', function (s,id){
$scope.riskAssessmentDTO.riskAssessmentKey = id;
$scope.viewTopRiskWin.open().center();
$scope.submit = function(){
rcsaAssessmentFactory.saveTopRisk($scope.topRiskDTO,id).then(function(){
$scope.viewTopRiskWin.close();
});
};
});
factory.js
var serializeTopRisk = function (topRisk,id) {
var riskAssessmentKey = id;
var objToReturn = {
topRiskName: topRisk.topRiskName,
mitigationActivityDes: topRisk.mitigationActivityDes,
issuePltfLookUpCode: topRisk.issuePltfLookUpCode,
issueNo: topRisk.issueNo,
riskAssessmentKey: topRisk.riskAssessmentKey
};
if(topRisk.riskAssessmentKey){
objToReturn.riskAssessmentKey = topRisk.riskAssessmentKey;
}
return objToReturn;
};
saveTopRisk: function(topRisk,id) {
var request = serializeTopRisk(topRisk);
console.log('request payload', JSON.stringify(request));
console.log('ID :: ', id);
var endpoint = 'app/assessment/rest/addTopRisks';
return $http.post(endpoint, request);
}
You forgot to pass the id to the serializeTopRisk function.
So you already pass the params correctly this this:
saveTopRisk: function(topRisk,id) {
var request = serializeTopRisk(topRisk);
But then serializeTopRisk should also get the id
var serializeTopRisk = function (topRisk, id) { // added the id over what you originally had
var riskAssessmentKey = $rootScope.riskAssessmentDTO.riskAssessmentKey; // drop this, use id instead
Don't use rootScope to pass data between the factory and the controller if you don't need to (it looks like you are already passing values to the factory from the controller by supplying it with object inputs, keep it that way and drop the rootScope usage from the factory).

Accessing Data from JavaScript Object's Array Member Variable

I'm writing a jQuery plugin for work which pulls in RSS feed data using Google's Feed API. Using this API, I'm saving all of the relevant RSS feed data into an object, then manipulating it through methods. I have a function which is supposed to render the RSS feed onto the webpage. Unfortunately, when I try to display the individual RSS feed entries, I get an error. Here's my relevant code:
var RSSFeed = function(feedTitle, feedUrl, options) {
/*
* An object to encapsulate a Google Feed API request.
*/
// Variables
this.description = "";
this.entries = [];
this.feedUrl = feedUrl;
this.link = "";
this.title = feedTitle;
this.options = $.extend({
ssl : true,
limit : 4,
key : null,
feedTemplate : '<article class="rss-feed"><h2>{title}</h1><ul>{entries}</ul></article>',
entryTemplate : '<li><h3>{title}</h3><p>by: {author} # {publishedDate}</p><p>{contentSnippet}</p></li>',
outputMode : "json"
}, options || {});
this.sendFeedRequest = function() {
/*
* Makes the AJAX call to the provided requestUrl
*/
var self = this;
$.getJSON(this.encodeRequest(), function(data) {
// Save the data in a temporary object
var responseDataFeed = data.responseData.feed;
// Now load the data into the RSSFeed object
self.description = responseDataFeed.description;
self.link = responseDataFeed.link;
self.entries = responseDataFeed.entries;
});
};
this.display = function(jQuerySelector) {
/*
* Displays the RSSFeed onto the webpage
* Each RSSEntry will be displayed wrapped in the RSSFeed's template HTML
* The template markup can be specified in the options
*/
var self = this;
console.log(self);
console.log(self.entries);
};
};
$.rssObj = function(newTitle, newUrl, options) {
return new RSSFeed(newTitle, newUrl, options);
};
// Code to call the jquery plugin, would normally be found in an index.html file
rss = $.rssObj("Gizmodo", "http://feeds.gawker.com/Gizmodo/full");
rss.sendFeedRequest();
rss.display($('div#feed'));
Obviously, my display() function isn't complete yet, but it serves as a good example. The first console.log() will write all of the relevant data to the console, including the entries array. However, when I try to log the entries array by itself, it's returning an empty array. Any idea why that is?
I guess the problem is that display() is called without waiting for the AJAX request to complete. So the request is still running while you already try to access entries - hence the empty array.
In order to solve this you could move the call to display() into the callback of $.getJSON(). You just have to add the required selector as a parameter:
this.sendFeedRequest = function(selector) {
var self = this;
$.getJSON(this.encodeRequest(), function(data) {
var responseDataFeed = data.responseData.feed;
...
self.entries = responseDataFeed.entries;
self.display(selector);
});
};
EDIT:
If you don't want to move display() into the callback, you could try something like this (untested!):
var RSSFeed = function(feedTitle, feedUrl, options) {
...
this.loading = false;
this.selector = null;
this.sendFeedRequest = function() {
var self = this;
self.loading = true;
$.getJSON(this.encodeRequest(), function(data) {
...
self.loading = false;
if (self.selector != null) {
self.display(self.selector);
}
});
};
this.display = function(jQuerySelector) {
var self = this;
if (self.loading) {
self.selector = jQuerySelector;
}
else {
...
}
};
};

Uncaught TypeError: Object has no method ... Javascript

I'm having an issue where I get an error that says...
"Uncaught TypeError: Object f771b328ab06 has no method 'addLocation'"
I'm really not sure what's causing this. The 'f771b328ab06' is a user ID in the error. I can add a new user and prevent users from being duplicated, but when I try to add their location to the list, I get this error.
Does anybody see what's going wrong? The error occurs in the else statement of the initialize function as well (if the user ID exists, just append the location and do not create a new user). I have some notes in the code, and I'm pretty sure that this is partly due to how I have modified an example provided by another user.
function User(id) {
this.id = id;
this.locations = [];
this.getId = function() {
return this.id;
};
this.addLocation = function(latitude, longitude) {
this.locations[this.locations.length] = new google.maps.LatLng(latitude, longitude);
alert("User ID:" );
};
this.lastLocation = function() {
return this.locations[this.locations.length - 1];
};
this.removeLastLocation = function() {
return this.locations.pop();
};
}
function Users() {
this.users = {};
//this.generateId = function() { //I have omitted this section since I send
//return Math.random(); //an ID from the Android app. This is part of
//}; //the problem.
this.createUser = function(id) {
this.users[id] = new User(id);
return this.users[id];
};
this.getUser = function(id) {
return this.users[id];
};
this.removeUser = function(id) {
var user = this.getUser(id);
delete this.users[id];
return user;
};
}
var users = new Users();
function initialize() {
alert("Start");
$.ajax({
url: 'api.php',
dataType: 'json',
success: function(data){
var user_id = data[0];
var latitude = data[1];
var longitude = data[2];
if (typeof users.users[user_id] === 'undefined') {
users.createUser(user_id);
users.users[user_id] = "1";
user_id.addLocation(latitude, longitude); // this is where the error occurs
}
else {
user_id.addLocation(latitude, longitude); //here too
alert(latitude);
}
}
})
}
setInterval(initialize, 1000);
Since I get the ID from the phone and do not need to generate it here (only receive it), I commented out the part that creates the random ID. In doing this, I had to add a parameter to the createUser method within Users() so that I can pass the ID as an argument from Initialize(). See the changes to createUser below:
Before, with the generated ID (the part where the number is generated is in the above code block with comments):
this.createUser = function() {
var id = this.generateId();
this.users[id] = new User(id);
return this.users[id];
};
After, with the ID passed as an argument:
this.createUser = function(id) {
this.users[id] = new User(id);
return this.users[id];
};
If anyone has any suggestions I would really appreciate it. Thanks!
Here you're getting user_id by :
var user_id = data[0];
So it's a part of the json answer : maybe a string or another dictionnary, this can't be a user object. You should try to update your code in your success function inside the "if" block by :
user = users.createUser(user_id);
//The following line is a non sense for me you put an int inside
//an internal structure of your class that should contain object
//users.users[user_id] = "1";
user.addLocation(latitude, longitude);

Categories

Resources