When I add $uibModalInstance to my controller I get the error:
Unknown provider: $uibModalInstanceProvider <- $uibModalInstance <- EventAdditionalInformationTabCtrl
My controller is defined as:
angular.module('myWebApp.controllers').
controller('EventAdditionalInformationTabCtrl', function ($scope, $uibModalInstance, eventData) {
});
I have another controller that defines the open function:
controller('modalCtrl', function ($scope, $uibModal) {
$scope.open = function (template, instance, size) {
var modalInstance = $uibModal.open({
animation: true,
templateUrl: template,
controller: instance,
size: size
});
};
}).
Then I want to pass the controller that will handle a specific instance of a modal, in this case EventAdditionalInformationTabCtrl.
My app is defined as:
var app = angular.module('myWebApp', [
'myWebApp.services',
'myWebApp.controllers',
'ui.router',
'duScroll',
'ngAnimate',
'ui.bootstrap',
'angularUtils.directives.dirPagination',
'angular-loading-bar'
]);
What am I missing?
EDIT ----
Here's how EventAdditionalInformationTabCtrl is linked to the view in ui-Router.
$stateProvider
.state('event', {
url: '/event',
params: {
eventId: null
},
resolve: {
eventData: ['$http', '$stateParams', function ($http, $stateParams) {
console.log('EventId: ' + $stateParams.eventId);
return $http.get('http://localhost:10569/api/eventView/' + $stateParams.eventId).then(function(response) {
return response.data;
});
}]
},
views: {
'': {
templateUrl: 'partials/events/event.html'
//controller: 'EventCtrl'
},
'eventHeader#event' : {
templateUrl: 'partials/events/event-header.html',
controller: 'EventHeaderCtrl'
},
'eventOverviewTab#event': {
templateUrl: 'partials/events/event-overview-tab.html',
controller: 'EventOverviewTabCtrl'
},
'eventDSOTab#event': {
templateUrl: 'partials/events/event-dso-tab.html',
controller: 'EventDSOTabCtrl'
},
'eventAdditionalInformationTab#event': {
templateUrl: 'partials/events/event-additional-information-tab.html',
controller: 'EventAdditionalInformationTabCtrl'
},
'eventFooter#event': {
templateUrl: 'partials/events/event-footer.html',
controller: 'EventFooterCtrl'
}
}
});
Where you have $uibModalInstance now should just be $uibModal. Use $uibModalInstance when you want to actually create a modal. This plunker is the official example for how to use $uibModal.
You need to inject '$uibModal' into your controller.
Check out the angular ui docs here https://angular-ui.github.io/bootstrap/#/modal
EDIT:
Change this
animation: true,
templateUrl: template,
controller: instance,
size: size
to this
animation: true,
templateUrl: template,
controller: EventAdditionalInformationTabCtrl,
size: size
Related
I've looked at similar questions but I can't seem to understand what I am missing. Basically, I have a service that gets data from the server, and I am trying to get that data into a controller through UI-Router's resolve property. However, after following numerous tutorials and documentations, I can't get the controller to find the data, so to speak. Everything comes up as undefined. I am hoping someone can help me understand what is happening. My code is below.
services.js
myServices.factory('SoundCloudService', ['$http', '$log', '$sce', function($http, $log, $sce) {
function getPlayerHtml() {
return $http.get('/get-site-data').then(function(oEmbed) {
return $sce.trustAsHtml(oEmbed.data.player);
});
};
function getSiteAbout() {
return $http.get('/get-site-data').then(function(oEmbed) {
return $sce.trustAsHtml(oEmbed.data.about);
});
}
function getAllTracks() {
return $http.get('/get-all-tracks').then(function(tracks) {
return JSON.parse(tracks.data);
});
};
function getAllPlaylists() {
return $http.get('/get-playlists').then(function(playlists) {
return JSON.parse(playlists.data);
})
};
function getPlaylist(pid) {
return $http.post('/get-playlist', pid, $http.defaults.headers.post).then(function(playlist) {
return playlist.data;
});
};
function getXMostTrendingFrom(x, playlist) {
var i, trending = [];
playlist.sort(function(a, b) { return b.playback_count - a.playback_count} );
for(i=0;i<x;i++) {
trending.push(all_tracks[i]);
}
return trending;
};
return {
getAllTracks: getAllTracks,
getAllPlaylists: getAllPlaylists,
getPlayerHtml: getPlayerHtml,
getSiteAbout: getSiteAbout,
getXMostTrendingFrom: getXMostTrendingFrom,
getPlaylist: getPlaylist,
};
}]);
app.js
myApp.config(['$stateProvider', '$urlRouterProvider', 'ngMetaProvider',
function($stateProvider, $urlRouterProvider, ngMetaProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('main', {
url: '',
template: '<ui-view/>',
abstract:true,
controller: 'MainController',
resolve: {
player: function(SoundCloudService) { return SoundCloudService.getPlayerHtml(); },
about: function(SoundCloudService) { return SoundCloudService.getSiteAbout(); },
}
})
.state('main.home', {
url: '/',
templateUrl: '../static/partials/home.html',
controller: 'IndexController',
})
.state('main.team', {
url: '/team',
templateUrl: '../static/partials/team.html',
controller: 'TeamController',
})
.state('main.contact', {
url: '/contact',
templateUrl: '../static/partials/contact.html',
controller: 'ContactController',
})
.state('main.resources', {
url: '/resources',
templateUrl: '../static/partials/resources.html',
controller: 'ResourcesController',
})
.state('main.listen-to', {
url: '/listen-to',
templateUrl: '../static/partials/listen-to.html',
controller: 'ListenController',
})
.state('main.listen-to.season', {
url: '/listen-to/:season',
templateUrl: '../static/partials/listen-to.season.html',
controller: 'ListenController',
})
.state('main.listen-to.season.episode', {
url: '/listen-to/:season/:episode',
templateUrl: '../static/partials/listen-to.season.episode.html',
controller: 'ListenController',
})
.state('main.read', {
url: '/read',
templateUrl: '../static/partials/read.html',
controller: 'ReadController',
})
.state('main.read.post', {
url: '/read/:post',
templateUrl: '../static/partials/read.post.html',
controller: 'ReadController',
})
}
]);
controller.js
myControllers.controller('MainController', ['$scope', '$log', 'PageTitleService',
function($scope, $log, PageTitleService, player) {
$log.log(player); /* This is always undefined */
}
]);
[UPDATE]
As pointed out by Hadi in the answer below, I placed player in the array, and the controller now looks like this:
skodenControllers.controller('MainController', ['$scope', '$log', '$sce', 'PageTitleService', 'player',
function($scope, $log, $sce, PageTitleService, player) {
$log.log(player);
}
]);
The console DOES show the data, but only after an error as such:
Error: [$injector:unpr]
http://errors.angularjs.org/1.3.2/$injector/unpr?p0=playerProvider%20%3C-%20player
at angular.js:38
at angular.js:3930
at Object.d [as get] (angular.js:4077)
at angular.js:3935
at d (angular.js:4077)
at Object.e [as invoke] (angular.js:4109)
at F.instance (angular.js:8356)
at angular.js:7608
at r (angular.js:347)
at I (angular.js:7607)
Hopefully someone can lead me in the right direction.
You forgot pass player into array. change to this
myControllers.controller('MainController', ['$scope', '$log',
'PageTitleService','player',
function($scope, $log, PageTitleService, player) {
$log.log(player); /* This is always undefined */
}
]);
As myServices and myControllers are both modules, ensure you add them as dependencies of myApp module.
// init myApp module
angular.module('myApp', ['myServices', 'myControllers']);
Edit
Some leads :
According to the documentation, when using ui-router nested views, child views (state name = main.xxx) must declare the parent state, so you must add parent: "main" or child views won't inherit resolved properties of main state controller
As siteDate is loaded asynchronously in SoundCloudService (services.js:23), you cannot be sure it will be available in your controllers which are loaded at the same time.
Instead, add a getSiteDate() method to SoundCloudService which returns a promise. siteData is then cached and immediately return by the promise.
For example :
/**
* #name getSiteData
* #description Scrap site data
* #returns {promise} a promise
*/
function getSiteData() {
var deferred = $q.defer();
if(siteData) {
deferred.resolve(siteData);
}
else {
$http.get('/get-site-data').then(function(response) {
siteData = response.data;
deferred.resolve(siteData);
}, function(err) {
deferred.reject(err.message);
});
}
return deferred.promise;
}
Why trying to map SoundCloudService to siteData ? You should simply inject SoundCloudService in controllers that use it :
For example :
skodenControllers.controller('MainController', ['$scope', '$log', '$sce', 'PageTitleService', 'SoundCloudService',
function($scope, $log, $sce, PageTitleService, SoundCloudService) {
// Note: getSiteData() could use a cache inside the service
SoundCloudService.getSiteData().then(function(siteData) {
...
});
}
I want to run a service that read total unread message when user visits a few particular page. I'm using resolve for this. I set up a factory which communicates with the backend through a http call and the backend returns the count of total messages and I wanna show this in html page but all I am getting is error.
( function () {
var countAllUnreads = function($location, $q, AuthService3)
{
var deferred = $q.defer();
AuthService3.fetchUnreadNotifications().then(function (res)
{
console.log('this is me');
$scope.numOfNotifications =res.data.totalUnread;
});
}
angular.module('myApp', [
'ngRoute',
'myApp.login',
'myApp.home',
'myApp.directory',
'myApp.forgotpassword',
'myApp.myProfile',
])
.factory('AuthService3', ["$http", "$location", function($http, $location){
var baseUrl = 'api/';
var fetchUnreadNotifications = function()
{
return $http.post(baseUrl + 'getAllUnreadNotifications');
}
return {fetchUnreadNotifications: fetchUnreadNotifications} ;
}])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/login', {
controller: 'LoginController',
templateUrl: 'app/components/login/loginView.html',
controllerAs: 'vm'
})
.when('/forgotpassword', {
controller: 'ForgotpasswordController',
templateUrl: 'app/components/forgotpassword/forgotpasswordView.html',
controllerAs: 'vm'
})
.when('/directory/:directoryType', {
controller: 'DirectoryController',
templateUrl: 'app/components/directory/directoryView.html',
resolve: {notifications:countAllUnreadsn,},
controllerAs: 'vm'
})
.when('/home', {
controller: 'HomeController',
templateUrl: 'app/components/home/homeView.html',
resolve: {notifications:countAllUnreadsn,},
controllerAs: 'vm'
})
.when('/myprofile', {
controller: 'MyProfileController',
templateUrl: 'app/components/profile/myProfileView.html',
resolve: {notifications:countAllUnreadsn,},
controllerAs: 'vm'
})
.otherwise({
redirectTo: '/login'
});
}]);
})();
The problem is that you are using $scope within the function which loads notifications. $scope will not be available there since it might not be created yet. You need to return a promise and the resolved value can be injected as a dependency to the controller.
var countAllUnreads = function($location, $q, AuthService3)
{
var deferred = $q.defer();
AuthService3.fetchUnreadNotifications().then(function (res)
{
deferred.resolve(res.data.totalUnread);
});
return deferred.promise;
};
And in your controllers, have a dependency for 'notifications'.
Ex: function HomeController($scope, $http, notifications){ }
I am using a great template for ionic tabs and side menu as having issues with the navigation from the tabs. But when I use the code pen example and structure the html files into a templates folder and update the app.js file I lose the navigation. I obviously do not understand the js link format correctly. Please could someone explain it to me.
My code pen is here
The original is here
app.js (each html file is in www/templates
angular.module('ionicApp', ['ionic'])
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('entry', {
url: '/entry/templates',
templateUrl: 'templates/entry.html',
controller: 'EntryPageController'
})
.state('main', {
url: '/main/templates',
templateUrl: 'templates/mainContainer.html',
abstract: true,
controller: 'MainController'
})
.state('main.home', {
url: '/home',
views: {
'main': {
templateUrl: 'templates/home.html',
controller: 'HomePageController'
}
}
})
.state('main.info', {
url: '/info',
views: {
'main': {
templateUrl: 'templates/info.html',
controller: 'InfoPageController'
}
}
})
.state('main.tabs', {
url: '/tabs',
views: {
'main': {
templateUrl: 'templates/tabs.html',
controller: 'TabsPageController'
}
}
})
$urlRouterProvider.otherwise('/entry');
}])
.controller('MainController', ['$scope', function ($scope) {
$scope.toggleMenu = function () {
$scope.sideMenuController.toggleLeft();
}
}])
.controller('EntryPageController', ['$scope', '$state', function ($scope, $state) {
$scope.navTitle = 'Entry Page';
$scope.signIn = function () {
$state.go('main.home');
}
}])
.controller('HomePageController', ['$scope', '$state', function ($scope, $state) {
$scope.navTitle = 'Home Page';
$scope.leftButtons = [{
type: 'button-icon icon ion-navicon',
tap: function (e) {
$scope.toggleMenu();
}
}];
}])
.controller('InfoPageController', ['$scope', '$state', function ($scope, $state) {
$scope.navTitle = 'Info Page';
$scope.leftButtons = [{
type: 'button-icon icon ion-navicon',
tap: function (e) {
$scope.toggleMenu();
}
}];
}])
.controller('TabsPageController', ['$scope', '$state', function ($scope, $state) {
$scope.navTitle = 'Tab Page';
$scope.leftButtons = [{
type: 'button-icon icon ion-navicon',
tap: function (e) {
$scope.toggleMenu();
}
}];
}])
enter code here
I am stuck with this from around one week. I am resolving my todo_id on "TodoDetailController", and then using a service to get todo details. But the controller is not working as expected. When I write a simple data on $scope its just not reflecting in my view, but the data in $rootscope is reflecting, But I don't want to use $rootscope everywhere.
Can someone please solve my query?
Here is the github project https://github.com/udayghulaxe/ticitic_todo
This is the project structure
This is what I have done so far
/************* My states config ************************/
.state('dashboard', {
url: '/dashboard',
abstract: true,
views: {
'': { templateUrl: './partials/main.html'},
'header_toolbar#dashboard': { templateUrl: './views/header_toolbar.html' },
'sidenavleft#dashboard': { templateUrl: './views/sidenav.html' },
'widgets#dashboard': { templateUrl: './views/widgets.html'},
'todo_detail#dashboard': { templateUrl: './views/todo_detail.html' }
}
})
.state('dashboard.listdetail', {
url: '/lists/:list_id/',
templateUrl: './partials/list.detail.html',
controller:'ListController',
resolve: {
list_id: function($stateParams){
return $stateParams.list_id;
}
},
data: {
authorizedRoles: [USER_ROLES.user],
pageTitle: 'Lists'
}
})
.state('dashboard.tododetail', {
url: '/lists/:list_id/:todo_id',
templateUrl: './partials/list.detail.html',
controller:'TodoDetailController',
resolve: {
list_id: function($stateParams){
//console.log($stateParams);
return $stateParams.list_id;
},
todo_id: function($stateParams){
//console.log($stateParams);
return $stateParams.todo_id;
}
}
})
/**************** My conrtoller *******************/
app.controller("TodoDetailController",['$rootScope','$scope','$state', '$q', 'UserService', '$window','AuthService','DataService','AUTH_EVENTS','list_id','$mdSidenav','todo_id',
function($rootScope,$scope, $state, $q, UserService, $window, AuthService, DataService,AUTH_EVENTS,list_id,$mdSidenav,todo_id)
{
/********* This data is not relecting at all **********/
$scope.list_id = list_id.toString();
$scope.current_list = UserService.GetTodoBylistid($rootScope.lists, $scope.list_id);
$scope.value = 'Not refelcting in view';
/**************** This is updating in view ***************************/
$rootScope.value2 = 'refelcting in view';
$scope.$watch(todo_id, function() {
$rootScope.todo_id = todo_id;
}, true);
toggleSidenav('right');
};
}]);
Inject $rootscope after $scope like this
app.controller("TodoDetailController",['$scope','$state','$rootScope', '$q', 'UserService', '$window','AuthService','DataService','AUTH_EVENTS','list_id','$mdSidenav','todo_id',
function($scope, $state, $rootScope, $q, UserService, $window, AuthService, DataService,AUTH_EVENTS,list_id,$mdSidenav,todo_id)
]);
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