While saving a new invoice using my AngularJS app, there is a noticeable time taken while the API is checking products balances, saving data...etc so I was wondering is there a way in AngularJS where I can show like an intermediate (page...example: #/processing) where the users get routed to once the user click the Save button then depending on the save new invoice $http result (failure or success) either route the user back to the invoice page (ex. #/new-invoice) OR the success saving page (#/thanks-for-ordering) ?
Any example is highly appreciated. Thanks
i am using spinner for such things... on http request start the spinner and on response stop it. use the http interceptor for the same. if you dont want to implement it yourself, below are few links.
angular-spinner or angular-sham-spinner
also read this BLOG which details how the spinner works
You can use ng-if to switch between a input and saving state.
Example template:
<div ng-if="isSaving"><img src="spinner.gif"> Saving...</div>
<form ng-if="!isSaving" ng-submit="saveTheThing(thing)>
<input ng-model="thing.title" type="text"/>
...
</form>
Example controller:
angular.module('app').controller('ExampleCtrl', function ($scope, $location) {
$scope.saveTheThing = function(thing) {
$scope.isSaving = true;
$http.post('api/things', thing).then(function (response) {
$location.path('/things/' + response.data.id); // Go to the success page
}).catch(function (error) {
$scope.error = error; // show error
}).finally(function () {
$scope.isSaving = false;
});
};
})
If you need IE8 support you'll need to replace .catch with ['catch'] and .finally with ['finally']
Although I wouldn't use a standalone url/route for a processing page.
You can store the save promise in a service.
angular.module('app').value('progress', {});
angular.module('app').controller('FormCtrl', function ($scope, progress, $location) {
$scope.saveTheThing = function(thing) {
progress.thing = $http.post('api/things', thing);
$location.path('/processing');
});
});
angular.module('app').controller('ProgressingCtrl', function (progress, $location) {
progress.thing.then(function () {
$location.path('/thank-you');
}, function (error) {
$location.path('/form');
});
});
Compared to the ng-if solution you now need additional work to:
Restore the form values on failure
Pass the error message to the FormCtrl
Define the refresh behavior for the progressing page
Related
I am using angularJS localstorage and i injected this very well but problem in code.
I want when localstorage gets new data, so that its call a function $scope.getAllContact() automatically.
I am trying to solve this issue coz, for example, i opened two tab in browser, if i change anything in one tab, the latest change should reflect in other tab too without any reload and refresh.
At first see my code:
app.controller('crudCtrl', function($scope, $http, $timeout, $localStorage, $sessionStorage) {
$scope.getAllContact = function() {
var data = $http.get("http://127.0.0.1:8000/api/v1/contact/")
.then(function(response) {
$scope.contacts = response.data;
// show something if success
}, function(response) {
//show something error
});
};
$scope.getAllContact();
// below method will post data
$scope.formModel = {};
$scope.onSubmit = function () {
$http.post('http://127.0.0.1:8000/api/v1/contact/', $scope.formModel)
.then(function(response) {
$localStorage.name = response.data;
$timeout(function() {
$scope.successPost = '';
}, 4000);
//below $scope will push data in client site if the request is success
$scope.contacts.push(response.data);
//if any error occurs, below function will execute
}, function(response) {
// do nothing for now
});
};
});
above in $scope.onSubmit() methond, i send the submitted data to localstorage too, so i need if localstorage gets new data, it should execute $scope.getAllContact() always automatically without any refresh.
Can anyone fix me this issue?
Use the storage event:
angular.element(window).on("storage", $scope.getAllContact);
$scope.$on("$destroy", function() {
angular.element(window).off("storage", $scope.getAllContact);
});
For information, see
MDN Window API Reference - storage_event
MDN Web API Reference - StorageEvent
I am setting up a registration page where after the user submits, they are emailed an activation link. When they click on the activation link in the email, I want the account get activated on the server and then I want my angularJS controller to catch the response from the server. I got the activation part working, but I am unsure on how to catch the response from my server since the call to the server did not originate from an angular view, but from an email.
Try out the below code:
Html:
<div ng-controller="activationCtrl as vm">
<h3>{{vm.activationSuccessMessage}}</h3>
<div>
Controller:
(function(){
'use strict';
angular
.module('your moduleName',[])
.controller('activationCtrl',activationCtrl);
activationCtrl.$inject = ['$http'];
function activationCtrl($http)
{
var vm = this;
vm.activationSuccessMessage = "";
var param = {}; //if any
$http.post('api/Users/Activate', param)
.then(function(response)
{
//Success - Do what you need to do.
vm.activationSuccessMessage = "Activation Successful";
}, function(response){
//Fail - Handle it.
vm.activationSuccessMessage = "Activation failed";
});
}
})();
Inside your activation page controller on load.
//Get activation value however you want to do that.
var activationToken = ValueFromURLSomehow.
//Can keep it simple, with a $http request directly in controller, or use a service.
$http.get('api/Account/Activate',{params{token:activationToken}}).then(function(response){
//Success - Do what you need to do.
}, function(response){
//Fail - Handle it.
});
I am trying to build an AngularJS single page application with Java Spring as rest service.
Currently my controller allows me to save all the filled data to the back end which I have something like this in my code:
$scope.$on('$destroy', function () {
personalDataService.saveData.query({}, {
personalData: $scope.personalData
}, function (res) {
console.log(res);
});
});
In another page, I loaded the part of the data from the same table in order to do some validation, for example checking if user is female to determine she needs to fill another form.
The problem is while I am leaving this page, the promise for save is not return yet, the second page has been loaded and the data is not completed. If I refresh the second page again then everything is back to normal
Is there any way to make sure all the promise has been return before destroy/ leaving this page?
Once the promise is resolved, emit a event.
function saveFields() {
var deferred = $q.defer();
// in your save fields function, resolve the promise on success save or reject the promise on error.
onSaveCall(args, onSuccess, onFail);
var onSucess = function() {deferred.resolve()};
return deferred.promise;
}
$scope.$on('destroy', function () {
onSaveCall.then(function () {
// Here your save fields is resolved then write your code to emit or notify.
})
})
If you have more than one promise use promises.all https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
Build an array of all your promises running (for example, by storing them in a service, in the $rootScope or via events) and wait for the completion by using $q.all():
$scope.$on('$destroy', function () {
$q.all($rootScope.promises).then(function(){
console.log('all promises finished');
});
}
I want to redirect to different page after successful submission of form in angularjs using firebase.
I am using push() for pushing data in database of firebase.Here is my controller implementation-
.controller('AddPostCtrl',['$scope','$location',function($scope,$location){
$scope.AddPost=function(event){
var firebaseObj=new Firebase("https://boiling-inferno-5476.firebaseio.com/Article");
event.preventDefault();
var title=$scope.article.title;
var post=$scope.article.post;
firebaseObj.push({
title:title,
post:post
},function(error){
if(error)
{
console.log(error);
}
else
{
$location.path('/welcome');
}
})
}
}])
On clicking submit button of form page should be redirected to 'welcome' page,but i have to click twice to do that.is there any error in my implementation.
Try this:
$scope.$apply(function() {
$location.path('/welcome');
});
The $location service uses the $digest phase to start the route change. That's why you have to use the $apply function when the $location service is used outside of the scope life cycle. And that's why your second click applied the route changed upon the first click.
I have a view within my App which does a database pull to show a user images they have previously uploaded.
The problem is that another view allows them to upload new images, but when switching back to the view of their uploaded images, they have to do a full page refresh to see their new uploads.
The question is how can I force the $http.get to run every time the view is loaded?
This is what I am trying but is not doing what I think it should:
capApp.controller('myUploadedPhotos', function ($scope, $http) {
$scope.nameFilter = "";
$http.get("/ajax/myUploadedPhotos.php", { cache: false})
.success(function(response) {
$scope.photos = response;
});
});
Is there a way to do this?
Your code looks correct so possibly the request is cached from the server? You can try appending a random string to your url to break the cache. e.g.
"/ajax/myUploadedPhotos.php" + new Date().getTime()
After thinking about it, I think you can also remove the { cache: false} because Angular also won't be able to cache the request if the timestamp changes. The old requests would just be sitting around somewhere taking up memory.
I'm not quite understand your question, but there isn't any issues with next initialization behaviour:
(function(angular) {
var capApp = angular.module('yourModule', []);
capApp.controller('myUploadedPhotos', ['$scope', '$http',
function ($scope, $http) {
$scope.nameFilter = "";
$scope.actions = angular.extend($scope.actions || {}, {
init: function () {
return $http.get("/ajax/myUploadedPhotos.php", {cache: false}).then(
function (response) {
$scope.photos = response;
}, function (reason) {
console.log('Error occured: ' + reason);
});
}
});
// You could even use it in $watch
$scope.actions.init();
}
]);
})(angular);