Correct way to destroy timeout in angularjs progressbars? - angularjs

I have the following code to display a progressbar:
var cancelTimeoutProcess = $timeout(function () {
if (defer !== null) {
vm.setProcessingParameters('No Message');
defer = vm.openProgressBar();
deferTimer.resolve();
}
}, 1000);
// cancel the $timeout service
$scope.$on('$destroy', function () {
if (cancelTimeoutProcess) {
$timeout.cancel(cancelTimeoutProcess);
cancelTimeoutProcess = null;
}
});
Wanted to confirm if this is the right way to launch a progressbar and destroy the timeout?

Related

Execute an Angular function only if the current tab is active in the browser

I have an angular js function which should be called for every 2 seconds only when the current tab is open in the browser. Is there any way to check whether the current page is active in the browser.
$scope.callAtInterval = function() {
var url = "http://127.0.0.1/test";
$http.get(url).success( function(response) {
$scope.initial = response;
},
function errorCallback(response) {
$scope.result=response;
});
}
$interval( function(){ $scope.callAtInterval(); }, 5000);
}
I think below piece of code is self-explanatory
import { HostListener} from "#angular/core";
#HostListener("window:visibilitychange", ["$event"])
onVisibilityChange($event) {
const isVisible = $event.target.visibilityState === 'visible';
this.logger.info(isVisible);
if (isVisible) {
// tab is visible
} else {
// tab is not-visible
}
}
You would use the focus and blur events of the window:
$(window).on("blur focus", function(e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
switch (e.type) {
case "blur":
// cancel your interval function
break;
case "focus":
// emit your interval function
break;
}
}
$(this).data("prevType", e.type);
})

AngularJS How to execute function after some function finish?

I have some page which contain register with facebook button which I set hidden with ng-hide="fbLoggedIn" and form input which I set hidden with ng-show="fbLoggedIn"
My goal is register with facebook button will hide if fbLoggedIn set to true and form input will show if fbLoggedIn set to true.
register facebook button ng-click="registerFb()" execute this function
$scope.registerFB = function () {
authService.fbLogin();
$scope.fbLoggedIn = authService.fb_logged_in();
console.log($scope.fbLoggedIn); //this show false even `fb_access_token` not null
}
Here is my authService.fbLogin and authService.fb_logged_in function
authService.fbLogin = function () {
var FB = window.FB;
FB.login(function(response) {
console.log(response);
if (response.authResponse) {
sessionService.set('fb_id', response.authResponse.userID);
sessionService.set('fb_access_token', response.authResponse.accessToken);
sessionService.set('fb_expiration_date', new Date(new Date().getTime() + response.authResponse.expiresIn * 1000).toISOString());
//console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
console.log(response);
});
} else {
console.log('User cancelled login or did not fully authorize.');
//console.log(response);
}
});
};
authService.fb_logged_in = function () {
if(sessionService.get('fb_access_token') != null){
return true;
}else {
return false;
}
};
In other function I try to check if fb_access_token is not null, just to make sure something wrong with my logic, and the result is true.
With above debuggin I can say that $scope.fbLoggedIn = authService.fb_logged_in(); execute before authService.fbLogin(); finish.
So how I can execute $scope.fbLoggedIn = authService.fb_logged_in(); after authService.fbLogin(); finish? maybe how to achieve my goal?
Alright. This can be achieved using promise. I don't know the parameters you have included in your autService service, so I will be making a factory of the same name with the new parameters that you might need to add.
Hence, according to me, this is how your factory should be.
angular.module('YourModuleName').factory('authService',['$http','$q',function($http,$q){
var obj = {};
obj.fbLogin = function () {
var defer = $q.defer();
var FB = window.FB;
FB.login(function(response) {
console.log(response);
if (response.authResponse) {
sessionService.set('fb_id', response.authResponse.userID);
sessionService.set('fb_access_token', response.authResponse.accessToken);
sessionService.set('fb_expiration_date', new Date(new Date().getTime() + response.authResponse.expiresIn * 1000).toISOString());
FB.api('/me', function(response) {
console.log(response);
defer.resolve('Good to see you, ' + response.name + '.');
});
}
else {
defer.reject('User cancelled login or did not fully authorize.');
}
});
return defer.promise;
}
obj.fb_logged_in = function () {
if(sessionService.get('fb_access_token') != null){
return true;
}else {
return false;
}
};
return obj;
}])
And thus, the function call from the controller should be as follows.
$scope.registerFB = function () {
authService.fbLogin().then(function(response){
$scope.fbLoggedIn = authService.fb_logged_in();
console.log($scope.fbLoggedIn);
},function(error){
console.error("Error : ",error);
});
}
Note: CODE NOT TESTED.
Hence it would solve the problem with the best practices of angularJS
use the $rootscope to assign values they provide event emission/broadcast and subscription facility.

Delay loading data in Angular JS

I have code like this
(function (app) {
app.controller('productListController', productListController)
productListController.$inject = ['$scope', 'apiService', 'notificationService', '$ngBootbox', '$filter'];
function productListController($scope, apiService, notificationService, $ngBootbox, $filter) {
$scope.products = [];
$scope.page = 0;
$scope.pagesCount = 0;
$scope.getProducts = getProducts;
$scope.keyword = '';
$scope.search = search;
$scope.deleteProduct = deleteProduct;
$scope.selectAll = selectAll;
$scope.deleteMultiple = deleteMultiple;
function deleteMultiple() {
var listId = [];
$.each($scope.selected, function (i, item) {
listId.push(item.ID);
});
var config = {
params: {
checkedProducts: JSON.stringify(listId)
}
}
apiService.del('/api/product/deletemulti', config, function (result) {
notificationService.displaySuccess('Deleted successfully ' + result.data + 'record(s).');
search();
}, function (error) {
notificationService.displayError('Can not delete product.');
});
}
$scope.isAll = false;
function selectAll() {
if ($scope.isAll === false) {
angular.forEach($scope.products, function (item) {
item.checked = true;
});
$scope.isAll = true;
} else {
angular.forEach($scope.products, function (item) {
item.checked = false;
});
$scope.isAll = false;
}
}
$scope.$watch("products", function (n, o) {
var checked = $filter("filter")(n, { checked: true });
if (checked.length) {
$scope.selected = checked;
$('#btnDelete').removeAttr('disabled');
} else {
$('#btnDelete').attr('disabled', 'disabled');
}
}, true);
function deleteProduct(id) {
$ngBootbox.confirm('Are you sure to detele?').then(function () {
var config = {
params: {
id: id
}
}
apiService.del('/api/product/delete', config, function () {
notificationService.displaySuccess('The product hase been deleted successfully!');
search();
}, function () {
notificationService.displayError('Can not delete product');
})
});
}
function search() {
getProducts();
}
function getProducts(page) {
page = page || 0;
var config = {
params: {
keyword: $scope.keyword,
page: page,
pageSize: 20
}
}
apiService.get('/api/product/getall', config, function (result) {
if (result.data.TotalCount == 0) {
notificationService.displayWarning('Can not find any record.');
}
$scope.products = result.data.Items;
$scope.page = result.data.Page;
$scope.pagesCount = result.data.TotalPages;
$scope.totalCount = result.data.TotalCount;
}, function () {
console.log('Load product failed.');
});
}
$scope.getProducts();
}
})(angular.module('THTCMS.products'));
So my problem is when i loading data the application take me some time to load data.
I need load data as soon as
Is the any solution for this?
Since you are loading data via api call, there will be a delay. To handle this delay, you should display a loading screen. Once the data is loaded, the loading screen gets hidden and your main screen is visible. You can achieve this using $http interceptors.
See : Showing Spinner GIF during $http request in angular
The api-call is almost certainly causing the delay. Data may be received slowly via the api-call so you could display any sort of loading text/image to notify the use that the data is being loaded.
If u want the data ready at the time when controller inits, u can add a resolve param and pass the api call as a $promise in the route configuration for this route.

pageshow not working in apache cordova

Hello I am trying to implement the "pageshow" because I need to block the return if the page button that will take is the login.Porém the method "pageshow" is not called , so I can not apply logic:
// and then run "window.location.reload()" in the JavaScript Console.
(function () {
"use strict";
var pageHistoryCount = 0;
var goingBack = false;
document.addEventListener('deviceready', onDeviceReady.bind(this), false);
function onDeviceReady() {
document.addEventListener('pause', onPause.bind(this), false);
document.addEventListener('resume', onResume.bind(this), false);
document.addEventListener('backbutton', backButtonHandler, false);
$(document).bind("pageshow", function (e, data) {
console.log("AAAAAAAAAAAAAAA");
if (goingBack) {
goingBack = false;
} else {
pageHistoryCount++;
console.log("HERE");
}
});
// TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
};
function onPause() {
};
function onResume() {
};
function exitApp() {
navigator.app.exitApp();
};
function backButtonHandler(e) {
e.preventDefault();
console.log(pageHistoryCount);
if (pageHistoryCount > 0) pageHistoryCount--;
if (pageHistoryCount == 0) {
} else {
goingBack = true;
console.log("Going back to page #" + pageHistoryCount);
window.history.back();
}
//Here implement the back button handler
};
})();

Protractor select values from drop down with promise

I'm running a protractor tests and filling in a form with dropdowns. How can I ensure that each dropdown has a promise that is resolved before moving onto the next one? Right now I'm using sleeps and know that can't be the right way.
Describe('Filling site utility form', function() {
beforeEach(function(){
var input_monthly = by.linkText('Input Monthly');
browser.wait(function() {
return browser.isElementPresent(input_monthly);
});
var field1 = element(by.id('field1'));
Test.dropdown(field1, 1);
var field2 = element(by.id('field2'));
Test.dropdown(field2, 1);
});
My dropdown function is:
dropdown = function(element, index, milliseconds) {
element.findElements(by.tagName('option'))
.then(function(options) {
options[index].click();
});
if (typeof milliseconds !== 'undefined') {
browser.sleep(milliseconds);
}
}
Not 100% sure what you mean but I suspect what you're interested in is this:
describe('Filling site utility form', function() {
beforeEach(function(){
var input_monthly = by.linkText('Input Monthly');
browser.wait(function() {
return browser.isElementPresent(input_monthly);
});
var promise1 = element(by.id('field1')).all(by.tagName('option')).get(1).click();
var promise2 = element(by.id('field2')).all(by.tagName('option')).get(1).click();
protractor.promise.all([promise1, promise2]).then(function() {
//what do you want to do next?
});
});
});

Resources