when I use ui.bootstrap, onEnter doesn't work - angularjs

I built web app with angular1 and webpack2.
I want to make modal popup with own state so I used ui.router and
ui.bootstrap.
But the problem is, onEnter method doesn't work.
below is my app.js,
and I brought codes about modal at here :
Open Modal and change URL without change the view in AngularJS
import angular from 'angular';
import 'angular-ui-router';
import 'angular-ui-bootstrap';
import 'angular-resource';
// controllers
import homeController from './pages/home/home-controller';
import playerController from './pages/player/player-controller';
import toolbarController from './components/toolbar-controller';
angular.module('907dg', [
'ui.router',
'ui.bootstrap'
])
.config(($stateProvider, $locationProvider) => {
$stateProvider
.state('home', {
url: '/',
template: require('./pages/home/home.html'),
controller: 'HomeController'
})
// modal codes
.state('player', {
url: '/player/:playerName',
onEnter: function($stateParams, $state, $modal) {
console.log('here is player modal');
$modal.open({
template: '<div><h1>PLAYER MODAL POPUP</h1></div>',
resolve: {},
controller: function($scope, $state) {
$scope.ok = function () {
$scope.$close();
};
$scope.dismiss = function () {
$scope.$dismiss();
};
}
}).result.then(function (result) {
// $scope.$close
}, function (result) {
// $scope.$dismiss
}).finally(function () {
// finally
return $state.transitionTo('home');
});
}
});
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
})
.controller('MasterController', ($scope) => {
$scope.greeting = 'HERE IS INDEX';
})
.filter('trustAsResourceUrl', ['$sce', function($sce) {
return function(val) {
return $sce.trustAsResourceUrl(val);
};
}]);
playerController();
homeController();
toolbarController();
and the controller that calls modal.
$scope.show = function (pName) {
$state.go('player', { playerName: pName });
};

Related

AngularJS: Angular UI Bootstrap, pass data from modal to controller

I have correctly setup my angular modal, now I want to pass my modal data back to my controller. I am using the below code.
First my controller calls my factory service that creates the modal popup:
$scope.mymodal = myService.openModal(data);
My service is as:
function openModal (data) {
var uData = null;
if (data) {
uData = {
userName : data.setName,
gender : data.gender
}
}
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: 'ModalController',
backdrop: 'static',
keyboard: false,
resolve: {
data: function () {
return uData;
}
}
});
modalInstance.result.then(function () {
return;
}, function () {
});
return modalInstance;
}
See my jsfiddle here for this: http://jsfiddle.net/aman1981/z20yvbfx/17/
I want to pass name & gender that i select on my modal back to my controller, which then populates my page. Let me know what is missing here.
I updated AboutController, ModalController and myService with comments.
Main idea is return data from ModalController with close method. Fiddle
var app = angular.module('myApp', ['ui.router','ui.bootstrap']);
app.controller('IndexController', function($scope, $log) {
});
app.controller("AboutController", ['$location', '$state', '$scope', '$filter','myService', function($location, $state, $scope, $filter, myService) {
var data = "";
$scope.mymodal = myService.openModal(data);
// after modal is close, then this promise is resolve
$scope.mymodal.then(function(resp){
console.log(resp);
})
}]);
app.controller("ModalController", function($location, $state, $scope, $filter, $modalInstance) {
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
$state.go('index');
};
$scope.done = function () {
// return data on close modal instance
$modalInstance.close({genger:$scope.gender,userName:$scope.userName});
};
});
app.factory('ApiFactory', function ($http) {
var factory = {};
return factory;
});
app.factory("myService",[ "$state", "$modal", "ApiFactory",
function ($state, $modal, factory) {
var service = {
openModal: openModal
};
function openModal (data) {
var uData = null;
if (data) {
uData = {
userName : data.setName,
gender : data.gender
}
}
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: 'ModalController',
backdrop: 'static',
keyboard: false,
resolve: {
data: function () {
return uData;
}
}
});
// on close, return resp from modal
modalInstance.result.then(function (resp) {
return resp;
}, function () {
});
// return modal instance promise
return modalInstance.result;
}
return service;
}
]);
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/index');
$stateProvider
.state('index', {
url: '^/index',
templateUrl: 'index.html',
controller: "IndexController"
})
.state('about', {
url: '^/about',
templateUrl: 'about.html',
controller: "AboutController"
})
}]);

angularjs resolve is undefined

so in my state, i have
angular.module('app', ['ui.router', 'chart.js'])
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/home',
component: 'home',
resolve: {
data: ['$http', function ($http) {
return $http.get('some api call')
.then(function (response) {
console.log("this is the response", response);
return response;
});
}]
}
});
}]);
then i get the proper response back. but when i check my resolve in here,
angular.module('app')
.component('home', {
templateUrl: 'Content/app/components/home.html',
bindings: {
resolve: '<'
},
controller: [
function () {
var vm = this;
vm.$onInit = function () {
console.log("this is the resolve", vm)
}
}]
});
i see that my resolve is undefined. Am i doing something wrong?
$stateProvider will bind what you specify inside the resolve object to your component, rather than binding the whole resolve object itself.
angular.module('app')
.component('home', {
templateUrl: 'Content/app/components/home.html',
bindings: {
data: '<'
},
controller: [
function () {
var vm = this;
vm.$onInit = function () {
console.log("this is the resolve", vm)
}
}]
});
Documentation link: https://ui-router.github.io/ng1/docs/latest/interfaces/state.statedeclaration.html#as-an-object

AngularJS: goto previous url with refresh using $window

I am a newbie of AngularJS using version 1.6.4, What i am trying to do is redirect user on previous page with a complete refresh. Right now i am getting back but page is not refreshing. Any idea how can i do that with a single line code.
user-login.component.js:
(function () {
"use strict";
var module = angular.module(__appName);
function controller(authService, $window, $location, $document) {
var model = this;
model.$onInit = function () {
//TODO:
};
model.login = function () {
authService.login(model.email, model.password).then(function (response) {
//$window.history.back();
//$window.history.go(-1);
//$window.location.href = '/';
console.log("url:"+$document.referrer);
//$document.referrer is showing undefined in console
$location.replace($document.referrer);
},
function (response) {
model.msg = response.error;
});
}
}
module.component("userLogin", {
templateUrl: "components/user-login/user-login.template.html",
bindings: {
email: "<",
password: "<"
},
controllerAs: "model",
controller: ["authService", "$window", "$location", "$document" controller]
});
}());
App.js:
"use strict";
//Global variables
var __apiRoot = "http://localhost:8000/api"; //No slash '/' at the end
var module = angular.module(__appName, [
"ui.router",
"angular-jwt"
]);
module.config(function ($stateProvider, $urlRouterProvider, $httpProvider, jwtOptionsProvider) {
$urlRouterProvider.otherwise('/app/home');
$stateProvider
.state("app", {
abstract: true,
url: "/app",
component: "appRouting"
})
.state("app.home", {
url: "/home",
component: "homeRouting"
})
.state("app.search", {
url: "/search/:q",
component: "searchRouting"
});
jwtOptionsProvider.config({
tokenGetter: ['authService', function (authService) {
return authService.getToken();
}],
whiteListedDomains: ['localhost']
});
$httpProvider.interceptors.push('jwtInterceptor');
});
If you are using angular-ui-router and have name of previous state then use :
$state.go('previousState', {}, { reload: true });
If you don't have the name of the previous state then you could use this piece of code it will run every time state change will occur.
$rootScope.previousState;
$rootScope.currentState;
$rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from,fromParams) {
$rootScope.previousState = from.name;
$rootScope.currentState = to.name;
console.log('Previous state:'+$rootScope.previousState)
console.log('Current state:'+$rootScope.currentState)
});
you can refresh page by simply using native javascript. window.location.reload()
use $location.replace(). You can get the previous URL of where you came from using $document.referrer. $location.replace($document.referrer)

templateUrl not rendering when modal opened from iFrame

I have a situation in the application, where I want to load an already available modal, in an iFrame of another application using the same codebase. For this I have used the following code :
new-user-module.js
(function () {
'use strict';
angular
.module('mo.pages.new-user.layouts', ['ui.router', 'ui.bootstrap', 'mo.pages.new-user.services'])
.config(['$stateProvider', newUserRouteConfiguration]);
function newUserRouteConfiguration($stateProvider) {
$stateProvider
.state('new-user', {
url: '/new-user',
onEnter: [
'mo.pages.new-user.services.NewUserPageService', function (newAttachmentPageService) {
newAttachmentPageService.openAttachmentModal();
}
]
});
}})();
new-user-service.js
(function () {
'use strict';
angular
.module('mo.pages.new-user.services')
.service('mo.pages.new-user.services.NewUserPageService', NewUserPageServiceFactory);
NewUserPageServiceFactory.$inject = [
'$stateParams',
'$modal'
];
function NewUserPageServiceFactory($stateParams, $modal) {
var service = {
openUserModal: openUserModal
};
return service;
function openUserModal() {
return function () {
$modal.open({
templateUrl: 'modules/pages/shared/modals/new-user/new-user-modal.html',
controller: 'mo.pages.shared.modals.NewUserModalController as vm',
windowClass: 'new-user-modal',
resolve: {
headerText: function() {
return 'header';
}
},
backdrop: 'static',
size: 'lg'
});
};
}
}})();
The issue, I am facing is that, the modal is loading, when the '/new-user' is getting called in the iFrame, but the templateUrl is not loading.
Check your console, I think you may find an error with your call to newAttachmentPageService.openAttachmentModal();
Since NewUserPageServiceFactory is registered as a service and not really a factory, it should not return anything. You should just be adding the method to the service object, for example:
function NewUserPageServiceFactory($stateParams, $modal) {
this.openUserModal = function() {
return function () {
$modal.open({
templateUrl: 'modules/pages/shared/modals/new-user/new-user-modal.html',
controller: 'mo.pages.shared.modals.NewUserModalController as vm',
windowClass: 'new-user-modal',
resolve: {
headerText: function() {
return 'header';
}
},
backdrop: 'static',
size: 'lg'
});
};
}
}
For a good illustration of the (slight) differences between services and factories see here
Let me know if this works

unable to open a modal with angular and ui.routes

I am trying to follow this example to show a bootstrap modal on a certain state. It works fine without a modal (so the state config should be ok). All needed dependencies (ie angular bootstrap) should be available.
when I do a console.debug($stateParams) before $modal.open I get the correct data, within the $modal.open-method however the stateParams from the last state are returned (the state I am coming from)
Any hints?
EDIT
the relevant state cfg:
.state('publications.view', {
parent: 'publications.productSelection',
url: '/{productSlug:[a-zA-Z0-9-]+}/{docID:[0-9]+}_{slug:[a-zA-Z0-9-]+}',
onEnter: ['restFactory', '$state', '$stateParams', '$modal',
function(restFactory, $state, $stateParams, $modal) {
console.debug($stateParams.docID);
$modal.open({
templateUrl: 'partials/publication.html',
resolve: {
publication: ['restFactory', '$stateParams',
function(restFactory, $stateParams) {
console.debug($state.params);
console.debug($stateParams);
return restFactory.view($stateParams.language, $stateParams.productSlug, $stateParams.docID);
}
]
},
controller: ['$scope', '$sce', 'publication', '$rootScope',
function($scope, $sce, publication, $rootScope) {
$rootScope.pageTitle = publication.data.data.publication.Publication.title;
$scope.publication = $sce.trustAsHtml(publication.data.data.publication.Publication.content);
}
]
});
}
]
});
You can get around this issue by injecting the current $stateParams into the onEnter function, save them as state in some service, and inject that service instead into your modal resolves.
I am adapting the code from here: Using ui-router with Bootstrap-ui modal
.provider('modalState', function($stateProvider) {
var modalState = {
stateParams: {},
};
this.$get = function() {
return modalState;
};
this.state = function(stateName, options) {
var modalInstance;
$stateProvider.state(stateName, {
url: options.url,
onEnter: function($modal, $state, $stateParams) {
modalState.stateParams = $stateParams;
modalInstance = $modal.open(options);
modalInstance.result['finally'](function() {
modalInstance = null;
if ($state.$current.name === stateName) {
$state.go('^');
}
});
},
onExit: function() {
if (modalInstance) {
modalInstance.close();
}
}
});
};
})
Then in your app config section
.config(function($stateProvider, $urlRouterProvider, modalStateProvider) {
modalStateProvider.state('parent.child', {
url: '/{id:[0-9]+}',
templateUrl: 'views/child.html',
controller: 'ChildCtrl',
resolve: {
role: function(Resource, modalState) {
return Resource.get({id: modalState.stateParams.id}).$promise.then(function(data) {
return data;
});
}
}
});
}

Resources