AngularJS UI Bootstrap Modal controller still working when modalInstance is closed - angularjs

I am working with AngularJS and UI Bootstrap
I open a modal for the user login.
It works fine, but the problem is when I try to return to the first page.
Seems like when the modal is closed, but the controller ('LoginInstanceCtrl') is still there and is listening for the event '$routeChangeSuccess'. So the modal doesn't exist now and I get an error.
.controller('LoginInstanceCtrl', ['$modalInstance', '$scope', function($modalInstance, $scope) {
//do stuff
$scope.$on('$routeChangeSuccess', function ($event, current) {
$modalInstance.close();
});
}])
Thanks
Edit
Here I put a link to the full code, the only difference with the real code is that in the modal I have an iFrame and the routing to the "second page" is made there.
https://github.com/agusgambina/angularModalError
Thank you in advance

Related

Which pop up modal can be used in the app in which ui-router has been used

I have created a webpage in which different pages are opened through the Use of the UI-router different states for the each page opened and each page have may modules which are integrated through ng-include, Now I have the requirement of the popup modal needs to be integrated in my webpage but the pop modal doesnt work as expected Is their any popup modal which I can used in my webpage
I am using ngDialog and ui router. Here you can read:
Modals and popups provider for Angular.js applications. No
dependencies. Highly customizable.
Works like a charm.
On the documentation page you can see how to pass the scope or any other information you will need into the scope of the dialog to create the logic you need in your modal dialog. Taken from the documentation:
$scope.value = true;
ngDialog.open({
template: 'externalTemplate.html',
className: 'ngdialog-theme-plain',
scope: $scope
});
With a controller:
ngDialog.open({
template: 'externalTemplate.html',
scope: $scope
controller: ['$scope', 'otherService', function($scope, otherService) {
// controller logic
}]
});
In your scenario it is perhaps possible to use an ng-click on your link. Do some logic in the ng-click function and then open the ngDialog in this function with the appropriate data. Does that make sense? Or is it perhaps better to first open the dialog and use the passed data to do the needed data loading in the dialog itself. Perhaps a better user experience! ;)
You Can use the Angular Modal service to create a modal.
Please refer to the below link.
https://angular-ui.github.io/bootstrap/

Getting data from Modal in Bootstrap UI

I've been aggressively working on an app that uses AngularJS and Bootstrap. To help, I've included the Bootstrap UI framework. I am successfully opening a dialog and closing the dialog. However, I'm not sure how to actually "get" the data when a user clicks "Save Item".
My Plunker is Here
As shown in the Plunker above, I have my controller defined like this:
var modalInstance = $modal.open({
templateUrl: 'item-dialog.html',
size: 'sm',
controller: function($scope, $modalInstance) {
$scope.saveItem = function () {
alert('Saving...');
alert('ID: ' + $scope.newItem.typeId);
alert('Data: ' + $scope.newItem.data);
};
$scope.cancelItem = function() {
$modalInstance.close(false);
};
}
});
When I go to show the id of the item the user selected, and the text the user entered, it doesn't work. newItem is undefined. However, in the markup, you can see ng-model="newItem.data"
How do I get the information that the user entered in my controller?
Thank you!
You are not passing the result back to the controller opening the modal when you close it, you just need to add this in the modal's controller:
$modalInstance.close($scope.newItem);
See plunk.
Another thing: I've found that if you do not manually initialize objects on the $scope of the modal controllers of angular ui, they do not get bound properly, hence the $scope.newItem={} in the controller of the modal.

AngularJS won't refresh the page if the link that is clicked is with the same URL as the current page

I noticed this on two of my projects where I'm using AngularJS, so I'm assuming it's an issue with AngularJS.
Let's say I have a button on the menu that says "Register" and takes me to /account/register page. But, if I'm on the /account/register page, clicking the button won't refresh the page. It's like the button is disabled. This is always happening when the link I want to click has the same URL as the current page I'm on. The URLs are simple Link. How can I remove this behavior?
Had the same problem with angular, adding target="_parent" attribute to the link made it work.
For who didn't understand, I have recorded my screen to display this issue.
Basically, there are somethings wrong of Angular.
If we place the navigation outside of the ng-app.
The app has already loaded.
Then we click again to this navigation.
The app will disappear with no reason.
I fixed it by adding target="_parent" or target="_self" attribute to the anchor tag as answered above.
Check more on Angular docs
You can check if the current url/state/hash is "/account/register" ... if yes then use reload method of the $route service.
AngularJs: Reload page
I didn't find any reasonable way to check the path inside view, but this could work:
view:
<a link-href="path/to/same/location">same location</a>
directive:
app.directive('linkHref', ['$location', '$route', function ($location, $route) {
return {
restrict: 'A',
link: function ($scope, $element, $attrs) {
$element.bind('click', function () {
if ($location.$$url == $attrs.activeLink) {
$route.reload();
} else {
$location.path($attrs.activeLink);
});
}
};
}]);
I had the same problem and found that if I removed $location (wasn't using anyways) that was listed in a factory the problem went away.
<a target="_self" href="/xxxxxxx"></a>
will fix this problem

How to use the same controller for modal and non-modal form in Angular UI Bootstrap?

I've got a modal with a registration form. The same form should be displayed at the bottom of the landing page not in a modal.
Currently my controller that handles registration modal takes $modalInstance as one of its parameters along $scope etc. If I add ng-controller="SignUpCtrl" to an element in the landing page, it doesn't work, because the controller wasn't created via $modal.open method and so Angular complains about Unknown provider: $modalInstanceProvider <- $modalInstance.
I've got a service for registering users (authService.signUp(data).then/catch...), but the controller itself does a bit more - handles input, emits events (e.g. with translated error messages), sets cookies etc.
What's the best way to handle such case without duplicating almost whole controller code? Should I move the code from controller into yet another, higher-level service?
After struggling for a long while I found a easier trick to reuse our Controller for both modal and normal case.
I found that we can pass caller's scope to modal controller, so I pushed modalInstance into $scope and passed it to the modal controller.
Now you don't have unknown provider problem because $scope is a well known one.
Below is an example:
CallerController = function($rootScope, ...) {
var modalScope = $rootScope.$new();
modalScope.modalInstance = $modal.open({
templateUrl: tempUrl,
controller: ReusableModalController,
scope: modalScope // <- This is it!
});
modalScope.modalInstance.result.then(function (result) {
// Closed
}, function () {
// Dismissed
});
};
ReusableModalController = function($scope, ...){
var dataToSendBack = 'Hello World';
$scope.modalInstance.close(dataToSendBack);
};
Cheers!
If you are using ui-router you can easily use the resolve from ui-router to provide a $uibModalInstance (was $modalInstance before):
$stateProvider
.state('conductReview', {
url: '/review',
templateUrl: '/js/templates/review.html',
controller: 'yourController',
resolve: {
$uibModalInstance: function () { return null; } // <- workaround if you want to use $uibModalInstance in your controller.
}
})
That way you can use your modal controller like a normal controller. If you inject $uibModalInstance in your controller it will be null.
If you want to use same controller for both modal form as well as landing page form, make use of
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
You can get all the data from modal form in selectedItem and use this in landing page form.
Also, how do you open the modal. If it is through a button, bind that ng-model to open modal using $modal.open.Don't create separate controller for your modal.Use the same one as your landing page. This way you can use 1 controller to open modal as well as other function after the modal is closed.
PS: Code snippet given here is from angular ui's page. Check that page's documentation for selectedItem

How to call controller's event after async treatments on the run part?

I look for a user's session in the run process, and i would like to open a modal if i got a specific information from the User.
The thing is i need to send the scope to the modal, so i have to open it from a controller.
The problem is, when angular load controller, the user is not logged yet.
I tried to $location.path('/'); after the run async process, but it doesn't call the indexCtrl twice (because i am already on the view he is binding).
So my question is, how could i "refresh" my controller at the User.getSession() callback or how could i approach the thing differently ?
angular.module('TEST').run(function($rootScope, $window, AuthenticationManager, $location) {
AuthenticationManager.getSession(function() {
$location.path('/'); //Unfortunately useless because it doesn't call the indexCtrl twice
});
};
angular.module('TEST').controller('indexCrtl', function($scope, $User) {
if ($User.nb_points === 10) //Not fired because the user is not logged at the first load
var Modal = $modal({scope: $scope, show: false, template: 'modal.html'});
};
I think you are looking for $route.reload()
Causes $route service to reload the current route even if $location
hasn't changed.
As a result of that, ngView creates new scope, reinstantiates the
controller.
Example on jsfiddle

Resources