I have to make a school exercise where i need to update a users information in the data base the edit field works in a modal and needs to immediately display the updated user information.
what angular functions do i need i have been reading the documentation but can't find what i need.
userFactory.editUser(vm.user).then(success, failure);
function success() {
vm.user.push(user);
}
function failure(error) {
vm.errorMessage = error;
}
$uibModalInstance.close(vm.user);
};
This is what I tried but it did not work.
success function should have a parameter user.
it should be-
function success(user) {
vm.user.push(user);
}
Related
Angular js function updating some record. After updating record i am calling search method to show data on view.
But record does not updated before that search method call that does not get data so show null on view.
I have separate button for search on its ng-click this search method call. After some second if i click that button it shows data on view.
my code is,
vm.Update = function (value)
{
var test = value;
searchCriteria = {
From: vm.From,
To: vm.To,
Region: vm.Region,
City: vm.SelectedCity
}
surveyService.UpdateVisit(searchCriteria,value).then(function (d) {
var Confrm = JSON.parse(d.data.data);
if (d.data.status) {
toastr.success(Updated, {
autoDismiss: false
});
}
else {
toastr.error(errorMsg);
}
});
vm.searchVisit(0);
}
This searchvisit call and service unable to update data in database so i do not get any record on view. When i call this searchvisit method from separate button for searching it shows record with updated data.
Hopes for your suggestions how to pause execution before calling searchvisit method or any alternative that it gets any response than move execution control to searchvisit method.
Thanks
This is due to the asynchronous nature in JS.
From your code, surveyService.UpdateVisit(searchCriteria,value) returns a promise. Thus, when vm.searchVisit(0); is called, surveyService.UpdateVisit(searchCriteria,value) has not been resolved yet, meaning updating is still in progress and have not been completed. There for vm.searchVisit(0); shows records that are not updated.
If your second function is dependent on the values of the first function call, please add it as shown below inside the success callback.
surveyService.UpdateVisit(searchCriteria,value).then(function (d) {
var Confrm = JSON.parse(d.data.data);
if (d.data.status) {
toastr.success(Updated, {
autoDismiss: false
});
}
else {
toastr.error(errorMsg);
}
//Add this here.
vm.searchVisit(0);
});
I want to update my data based on data received from back-end
there are two functions:
function getData(data){
Service.getRequest(url).then(function (_response) {
console.log(_response)
var res = _response
if(res.data.success) {
$scope.$watch('data.photo', function() {
alert('hey, myVar has changed!');
});
data.photo = res.data.result;// this will tell that Image received against the corresponding data
}
else {
ctrl.errorCallBack = true
ctrl.errorFunction = 5
}
$rootScope.showPreloader = false;
});
}
now I have second function that receives the selected data and called when clicked on button , now question is can I update the data inside this function when above Get request is completed:
function syncData(data) {
console.log('image received')
console.log(data)
}
First function is called n times based on number of images , now user click on second function to view Image but user don't see any Image because Image is not received yet but I want a way to update second function as Image is received
examples
ist image is loaded....user doesn't click on second function
2nd image is pending....user clicks on second function or second function is active
2nd image is received....active function image received
https://plnkr.co/edit/zKeDT84W6eF9cc3FpcmG?p=preview
If you use $scope for variables they will be automatically sync with DOM whenever it changes.
I did some changes for you in plnkr i hope solve your problem.
http:// plnkr.co/edit/Ug53a03kB7Ap1EWf2jZK?p=preview
I have an AngularJS app using the Angular Material UI framework.
The app has different mechanisms showing dialogs (e.g error and loading spinner) and it would be preferable to only close one specifically chosen in certain scenarios, e.g. when an AJAX request is finished fetching data, I would like my loading spinner to close, but not any error dialog that may be the result of the fetching.
What I can find in documentation and code doesn't agree (though code should win the argument):
Documentation says only the latest can be closed, with an optional response
The code says the latest, a number of latest or all open can be closed, with an optional reason
Example in the documentation says a specific dialog can be closed, with a flag denoting how or why
I have made a demo of my intent, as MCV as possible – these are the highlights:
var dialog = {},
promise = {};
function showDialogs(sourceEvent) {
showDialog(sourceEvent, "one");
showDialog(sourceEvent, "two");
}
function showDialog(sourceEvent, id) {
dialog[id] = $mdDialog.alert({...});
promise[id] = $mdDialog.show(dialog[id]);
promise[id].finally(function() {
dialog[id] = undefined;
});
}
function closeDialogs() {
$mdDialog.hide("Closed all for a reason", {closeAll: true});
}
function closeDialogLatest() {
$mdDialog.hide("Closed from the outside");
}
function closeDialogReason() {
$mdDialog.hide("Closed with a reason");
}
function closeDialogSpecific(id) {
$mdDialog.hide(dialog[id], "finished");
}
EDIT:
I know the code always wins the argument about what happens, but I wasn't entirely sure it was the right code I was looking at.
I have updated the examples to better test and illustrate my point and problem. This shows things to work as the code said.
What I'm really looking for is whether it might still be possible to achieve my goal in some other way that I didn't think of yet.
Using $mdPanel instead of $mdDialog I was able to achieve the desired effect; I forked my demo to reflect the changes – these are the highlights:
var dialog = {};
function showDialogs() {
showDialog("one");
showDialog("two");
}
function showDialog(id) {
var config = {...};
$mdPanel.open(config)
.then(function(panelRef) {
dialog[id] = panelRef;
});
}
function closeDialogs() {
var id;
for(id in dialog) {
closeDialogSpecific(id, "Closed all for a reason");
}
}
function closeDialogSpecific(id, reason) {
var message = reason || "finished: " + id;
if(!dialog.hasOwnProperty(id) || !angular.isObject(dialog[id])) {
return;
}
if(dialog[id] && dialog[id].close) {
dialog[id].close()
.then(function() {
vm.feedback = message;
});
dialog[id] = undefined;
}
}
I would suggest having two or more dialogs up at the same time isn't ideal and probably not recommended by Google Material design.
To quote from the docs
Use dialogs sparingly because they are interruptive.
You say:
when an AJAX request is finished fetching data, I would like my
loading spinner to close, but not any error dialog that may be the
result of the fetching.
My solution here would be to have one dialog which initially shows the spinner. Once the request is finished replace the spinner with any messages.
I am using breezeJS with Entity Framework to provide input labels for user input fields, using a ui-bootstrap modal dialog. Because I need an initialized entity, I also need to provide the entity with an entity key, which I believe is described at http://breeze.github.io/doc-js/inside-entity.html under "Detached entities." If I do not change the key value in the modal, all is well. However, that is supposed to be a placeholder key until the user inputs the appropriate key. When that occurs, manager.saveChanges() catches an error. I have tried initializing the entity as detached, completing the modal, then adding to the manager, but no success there either. Any ideas on how to initialize an entity with a default key which will be immediately be replaced by a user? Thanks!
//datacontext.js
function saveChanges() {
if (createItem.entityAspect.entityState.isDetached()) {
manager.addEntity(createItem);
}
if (manager.hasChanges()) {
manager.saveChanges()
.then(saveSucceeded)
.catch(saveFailed);
} else {
console.log("Nothing to save");
}
function saveSucceeded() {
console.log("Save succeeded");
return;
}
function saveFailed() {
console.log("Save failed");
return;
}
}
function newItem() {
createItem = manager.createEntity('Some_Entity_Type',
{ aPI: '1000001' }, breeze.EntityState.Detached);
return createItem;
};
It looks like the issue was initializing with an actual primary key value. Initializing with
function newItem() {
createItem = manager.createEntity('Some_Entity_Type',
{ aPI: 0 }, breeze.EntityState.Detached);
return createItem;
};
acts as a temporary placeholder until the user enters the actual key. My larger problem was resulting from having different types of input boxes in the ui-modal, where each was of type="text", so the key value was entered as text and an error was thrown.
I think someone must have run into this situation before. Basically I have a big "form" which is composed of multiple smaller "forms" inside. (In fact, they are not real forms, just sets of inputs that are grouped together to collect info for models).
This form is for a checkout page, which contains:
shipping address
shipping method
billing address
billing method
other additional info such as discounts code input, gift wrapping etc.
I would like to update the user filled info to the server as soon as they complete each part (for example, when they complete shipping address). However, I want to make it work seamlessly without the need for the users to click some kind of "update" button after filling each partial part. I wonder if there is some way to go around this?
You'll want to $watch the fields in question and act upon them (say save to db) when they are filled in. The issue you will run into is how to determine when a user has filled fields in. Things like onblur etc don't work very well in practice. I would recommend using what is called a debounce function which is basically a function that allows the user to pause for X amount of time without our code going "ok done! now let's.. ohh wait still typing..."
Here's an example that I use on my own cart - I want to automatically get shipping quotes once I have an address so I watch these fields, allow some pausing with my debounce function then call my server for quotes.
Here's some controller code:
// Debounce function to wait until user is done typing
function debounce(fn, delay) {
var timer = null;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
};
}
// Apply debounce to our shipping rate fetch method
var fetch = debounce(function() {
$scope.fetching = true;
cartService.updateShipping($scope.shipping, function(data) {
$scope.fetching = false;
$scope.quotes = data;
});
}, 1000);
// Watch the shipping fields - when enough done and user is done typing then get quote
$scope.$watch('shipping', function(newVal, oldVal) {
// I use this to play around with what fields I actually want before I do something
var fields = ['street', 'region', 'name', 'postal', 'country', 'city'];
var valid = true;
fields.forEach(function(field) {
if (!$scope.form[field].$valid) {
valid = false;
}
});
if (valid) fetch();
}, true);
My form fields are setup like this:
<input type="text" name="street ng-model="shipping.street" required>
<input type="text" name="name" ng-model="shipping.name" required>
Notice how I make them part of a "shipping" object - that allows me to watch the shipping fields independently of others such as billing.
Note that the above is for the extreme cases such as shipping fields. For simple things such as subscribing to a newsletter if they check a box then you don't need to use the above and can simply do an ng-click="spamMe();" call in your checkbox. That function (spamMe) would be in your controller and can then call your server etc...
var spamMe = function() {
// Grab the email field that might be at top - ideally check if it's filled in but you get the idea
var email = $scope.email;
$http.post('/api/spam', ....);
}
I'd apply a $scope.$watch on each of those variables to trigger a function that checks to see if all the fields for a given section are filled out, and if so, then submit it to the server as an ajax request.
Here's my attempt at writing this:
var shippingFields = ['address', 'city', 'state', 'zip'] // etc
function submitFieldsWhenComplete(section, fields) {
fieldValues = fields.forEach(function (field) {
return $scope[section][field]
});
if (fieldValues.every()) {
// We've got all the values, submit to the server
$http.post({
url: "/your/ajax/endpoint",
data: $scope.shipping
})
}
}
shippingFields.forEach(function(field) {
$scope.$watch(function() {
return $scope['shipping'][field]
}, function(val) {
submitFieldsWhenComplete('shipping', shippingFields);
});
});