angularjs templates not hiding div from route - angularjs

It's two page user registeration process depending on the role the second page could be different but the first page will always remain the same. what I want I that user can go forward and backwards on both screens with persistent data. I trying a static page at start and then hide it and add the second template from route.
This is my angular app controller.
app.controller('addlandlordController' , function($scope , $http , $route ,API_URL , $routeParams , uploadService ){
$scope.API_URL = API_URL;
$scope.landVisible = true;
$scope.IsVisible = true;
if( $routeParams.test)
{
scope.$apply(function () {
$scope.IsVisible = false;
});
alert( $routeParams.test);
}
$scope.adduser = function($route){
var data = $.param({
fName: $scope.firstName,
lName: $scope.lastName,
role: 'landlord',
email: $scope.email,
linkId: $scope.linkId,
password: $scope.password,
});
var config = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
}
}
$http.post(API_URL + 'user' , data , config)
.then(
function(response){
//$scope.IsVisible = false;
//alert('success');
},
function(response){
// failure callback
alert('fail');
}
);
}
});
I have a div in html like this,.
<div id="content" class="container1" ng-controller='addlandlordController' >
<div ng-show = "IsVisible">
And following is my route in config,.
app.config(function($routeProvider){
$routeProvider.when('/landlord' , {
templateUrl : 'template/addlandlord.html',
controller : 'addlandlordController',
resolve: {
test: function ($route) { $route.current.params.test = true; }
}
})
});
What I want is that when the user click on the following button.
Create an Account</button>
On click that button #/landlord will be added to the url and the route config code will run and add the other template in ng-view which is happening. Now next step is to hide the old div above in such a way that when user go back one sten only the previous code should show and when user goes again into the next screen only the next template should be visible and mean while data should remain same for the both views.
Issues I am facing is
Css is for template view is missing although the css files are already in the commen header. But appears when a place css in the style within template.
if I hide the first div in the response of adduser then if user go back it still hidden. it doesn't appears unless I refresh the page.
But if went to hide it through route config the value turn false but div never hides.

Please check this
scope.$apply(function () {
$scope.IsVisible = false;
});
You are using $apply on scope, but not in $scope.
And $applyAsync is preferable method to trigger digest without risking of error "$digest already in progress"
$applyAsync example:
$element.on('click', ()=>{
$scope.model.testValue = 'I have been updated not from angular circle';
$scope.$applyAsync();
});
Link to the docs
Nice article to read

Related

angular ng-if keeps refreshing page

I have the following divs setup where I switch between a loading div and an angular view. Only the loading div should show up when globalCtx.viewportLoading == true, and only the ng-view should show up when globalCtx.viewportLoading == false:
<div id="viewContainer">
<div class="loader" ng-if="globalCtx.viewportLoading"></div>
<div ng-view ng-if="!globalCtx.viewportLoading"></div>
</div>
The variable globalCtx is defined in an angular service like so:
app.factory("globalCtx", function () {
var service = {
viewportLoading: false
};
return service;
});
On every route, I have a different view and a different angular controller. For each of these views, I show the loading div until the page loads like so:
Generate Request
var req = {
method: 'POST',
url: 'api/v1/work/do-something',
data: request,
headers: {
'Content-Type': "application/json; charset=utf-8"
}
}
Set Loading to True
globalCtx.viewportLoading = true
Make Request, and set viewportLoading to false on reply
$http(req).then(function (resp) {
// ... do something ...
globalCtx.viewportLoading = false
},
function (resp) {
alert('Error fetching data from server!');
});
This works for the first page I run on. Say, the home page. But any page I route to after that, it just keeps refreshing that page. Say, I Go to the home page. It makes one request for data. I then route to page1, and I notice the angular controller for page1 keeps refreshing and is being created over and over again. Why is this? Does it have to do with ng-if?
Please use this code for loading your view
globalCtx.viewportLoading = false;
$scope.$on('$viewContentLoaded', function(){
globalCtx.viewportLoading = true;
});

My $scope value not updating

updated object is not getting without using location.reload
Hi i will get list of objects from API where i have to update one value,After updating that value in modal popup i am not able to get new updated value without using location.reload. Is there any other solution for this.i am using two different controllers.
Will get list of objects from this
$scope.groups=response.data
will ng-repeat this groups where i will have edit button for every line,Once i click edit button popup will open
$scope.editGroup = function(u) {
$scope.groupName=u.groupName;
$scope.groupId=u.groupId;
ModalService.showModal({
templateUrl: 'app/components/modal/editGroupDetails.html',
controller: "ModalController",
scope: $scope
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$scope.message = "You said " + result;
});
});
};
Next once i edit the GroupName i will click submit
$scope.updateGroupName=function(){
var data={
"groupId": $scope.groupId,
"groupName": $scope.groupName
}
url=globalUrlConfig.globalAdminApi+globalUrlConfig.updateGroup+$scope.schoolId;
$http({
method: 'PUT',
url: url,
data: data,
}).success(function(response) {
console.log(response)
if(response._statusCode==200){
alert(response.data);
location.reload();
}
else{
alert("not updated")
}
})
}
Without using location.reload i am not able display updated data
Use $rootscope like this
Add this $rootScope.$emit("refreshData", {});
instead of Location.reload();
And then add this in your main controller for load data without refresh
var RefreshValue = $rootScope.$on("refreshData", function () {
GetValueMethod(); // call your method (List of object) for get data without reload form
});
$scope.$on('$destroy', RefreshValue);
Don't forget to inject $rootScope.

calling controller function from within a promise in external JS

Ionic Tabs, root of tabs HTML has "RootTabCtrl", and "Tab1" (with "Tab1_Ctrl") has a form, other tabs are disabled.
User submits form on Tab1
Tab1 Controller function kicks off.
Controller Function calls an external function (not in controller).
External function triggers, which executes a promise
In promise "results", returned data is processed
If X in returned data is true, trigger "RootTabCtrl" function to enable the other disabled tabs.
I can track console messages triggering every step of the way.
This all works except for this following odd behavior. "RootTabCtrl" doesn't enable the disabled tabs until the user clicks the form submit a second time...even though I see console messages saying it is in (at the end) of the RootTabCtrl function. I see all the same console messages from the first click - but on the 2nd time is when the disabled tabs get enabled again.
If I move step 6 outside of the promise in Step 4, and put it after step 3 (and before the promise), then all the tabs get enabled on the 1st click. However, this is no longer taking into account the value of X to determine if other tabs should be re-enabled or not.
What can I look for, or am not aware of, that would be causing this?
app.js:
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html",
controller: 'TabsCtrl'
})
// Each tab has its own nav history stack:
.state('tab.tab1', {
url: '/map',
views: {
'tab-1': {
templateUrl: 'templates/tab-1.html',
controller: 'tab1Ctrl'
}
}
})
controllers:
.controller('TabsCtrl', function($scope,$rootScope,constants) {
$scope.constants = constants ;
$scope.tabControl = {
disableRides : true,
disableBikes : true,
disableTransit : true
}
var refreshFinalizer = $rootScope.$on('updateTabsRefresh', function (event, data) {
console.log("Refresher 1") ;
$scope.tabControl.disableTab2 = false;
$scope.tabControl.disableTab3 = false ;
console.log("Refresher 2") ;
});
$scope.$on('$destroy', function () {
console.log("Destroy") ;
refreshFinalizer ();
});
})
.controller('tab1Ctrl', function($scope,$rootScope) {
$scope.setInfo= function() {
getGoogle(document.getElementById('form_data').value,0);
}
$scope.enableTabs = function(type) {
console.log("Here enableTabs1") ;
$rootScope.$broadcast('updateTabsRefresh');
console.log("Here enableTabs2") ;
}
})
Tab1 has a form, upon click, it executes $scope.setInfo. Then getGoogle() is in an outside JS function, its a call to google maps, and if specific data X is true, then enable all the other tabs using tab1Ctrl $scope.enableTabs() :
function getGoogle(userInfo,clear) {
console.log("setInfo 1") ;
geoCoder.geocode({'address': userInfo}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
// extra code removed
startPointSet = 1;
// tab1Ctrl html has id of "Tab1"
angular.element(document.getElementById('Tab1')).scope().enableTabs();
/* alternative method, worked the same as previous line but with same problem
var $sBody = angular.element(document.body) ;
var $sRootScope = $sBody.injector().get('$rootScope') ;
$sRootScope.$broadcast('updateTabsRefresh') ;
*/
console.log("setInfo 2") ;
}
} else {
// extra code removed
console.log(response) ;
}
});
}
}
All of the above works...except that when the call to enableTabs (within the google response), even though it correctly calls enableTabs and I can see the console.log messages firing from within enableTabs - the other tabs don't "enable" until the form button is clicked a 2nd time (and then I see all the console messages again). I tried 2 different methods, from within getGoogle(), both worked exactly the same - 1st clicked fired all functions correctly, but tabs did not enable. 2nd click fired all the functions and then the tabs got enabled.
Try this previous answer. Are you using $http calls? If so I have never actually had to do that so it seems like something else might be the root cause.
UPDATE
How about creating an Angular Service for this GetGoogle function call. Then you will still be inside of angular and can inject $rootScope and anything else that you need. You will need to inject this service into your tab1Ctrl (the myGoggleService below). I would also probably just pass the form back on the ng-submit:
Html
ng-submit="setInfo(formNameGoesHere)"
Controller
.controller('tab1Ctrl', function($scope, $rootScope, myGoogleService) {
$scope.setInfo = function(form) {
myGoogleService.getGoogle(form);
}
$scope.enableTabs = function(type) {
console.log("Here enableTabs1");
$rootScope.$broadcast('updateTabsRefresh');
console.log("Here enableTabs2");
}
});
Service: If you haven't created any already you will need to register it in your app.js like any directives you have and also put them in your index.html page like a regular controller.
.service('myGoggleService', [ '$rootScope', function ($rootScope) {
this.getGoogle = function(userInfo,clear) {
console.log("setInfo 1") ;
geoCoder.geocode({'address': userInfo}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$rootScope.$broadcast("updateTabsRefresh");
} else {
}
});
}
}}]);
I did copy your code from above and then just removed some of the extra stuff just to get the point across. Obviously could not run the code so there might be some mistakes or slight changes needed, but hopefully this will get you close.

Changing states but controller is not being called in angular js

I have a webpage which displays the user profile information from the database which is working fine, and another one in which user edits his/her information, which is edited in the database, which is also working. But after I change the data in the second webpage, I have changed the state to the first page using $state.go, which also seems to be working, but the newly updated data is not showing in this first page, the controller is not being called I think.
This is my controller of webpage which shows the userprofile :
.controller('myProfileCtrl', function (..parameters..) {
$scope.id = window.localStorage.getItem("profileId");
$scope.$root.loading = true;
$http.get('my link...')
.success(function (data) {
$scope.first_name = data[0].first_name;
$scope.middle_name = data[0].middle_name;
})
This is the controller of my second page which updates the user information :
.controller('editPersonalCtrl', function (..parameters..) {
$scope.saveChanges = function (user) {
$http.post('my link..', {
changeFirstName : new_first_name,
changeMiddleName : new_middle_name,
})
.success(function (data) {
$state.go('profile');//Go to the first webpage
$ionicHistory.nextViewOptions({
disableBack: true,
historyRoot: true
});
})
.error(function (data) {
alert("ERROR" + data);
});
}
The state changes but the newly updated data is not shown, I mean the controller of the first webpage is not working, otherwise it would have fetched the new data from the database and displayed it. The old data is showing.
replace
$state.go('profile');
with
$state.go('profile', {}, { reload: true });
It will force the to transit and than also it's not working you can do like
$state.go('profile', {}, {reload: true,notify: true});
This will force and also will broadcast $stateChangeStart and $stateChangeSuccess events. Here is the ref

Angular UI Router Reload Controller on Back Button Press

I have a route that can have numerous optional query parameters:
$stateProvider.state("directory.search", {
url: '/directory/search?name&email',
templateUrl: 'view.html',
controller: 'controller'
When the user fills the form to search the directory a function in the $scope changes the state causing the controller to reload:
$scope.searchDirectory = function () {
$state.go('directory.search', {
name: $scope.Model.Query.name,
email: $scope.Model.Query.email
}, { reload: true });
};
In the controller I have a conditional: if($state.params){return data} dictating whether or not my service will be queried.
This works great except if the user clicks the brower's forward and/or back buttons. In both these cases the state (route) changes the query parameters correctly but does not reload the controller.
From what I've read the controller will be reloaded only if the actual route changes. Is there anyway to make this example work only using query parameters or must I use a changing route?
You should listen to the event for succesful page changes, $locationChangeSuccess. Checkout the docs for it https://docs.angularjs.org/api/ng/service/$location.
There is also a similar question answered on so here How to detect browser back button click event using angular?.
When that event fires you could put whatever logic you run on pageload that you need to run when the controller initializes.
Something like:
$rootScope.$on('$locationChangeSuccess', function() {
$scope.searchDirectory()
});
Or better setup like:
var searchDirectory = function () {
$state.go('directory.search', {
name: $scope.Model.Query.name,
email: $scope.Model.Query.email
}, { reload: true });
$scope.searchDirectory = searchDirectory;
$rootScope.$on('$locationChangeSuccess', function() {
searchDirectory();
});
Using the above, I was able to come up with a solution to my issue:
controller (code snippet):
...var searchDirectory = function (searchParams) {
if (searchParams) {
$scope.Model.Query.name = searchParams.name;
$scope.Model.Query.email = searchParams.email;
}
$state.go('directory.search', {
name: $scope.Model.Query.name,
email: $scope.Model.Query.email,
}, { reload: true });
};...
$rootScope.$on('$locationChangeSuccess', function () {
//used $location.absUrl() to keep track of query string
//could have used $location.path() if just interested in the portion of the route before query string params
$rootScope.actualLocation = $location.absUrl();
});
$rootScope.$watch(function () { return $location.absUrl(); }, function (newLocation, oldLocation) {
//event fires too often?
//before complex conditional was used the state was being changed too many times causing a saturation of my service
if ($rootScope.actualLocation && $rootScope.actualLocation !== oldLocation && oldLocation !== newLocation) {
searchDirectory($location.search());
}
});
$scope.searchDirectory = searchDirectory;
if ($state.params && Object.keys($state.params).length !== 0)
{..call to service getting data...}
This solution feels more like a traditional framework such as .net web forms where the dev has to perform certain actions based on the state of the page. I think it's worth the compromise of having readable query params in the URL.

Resources