Angular Component/Controller resolve $stateprovider - angularjs

I am trying to adapt to Angular's component (from code generated by Angular Fullstack Generator).
I tried to configure the routes to resolve "query" as per below:
angular.module('paizaApp')
.config(function($stateProvider) {
$stateProvider
.state('main', {
url: '/',
template: '<main query="$resolve.query"></main>',
resolve:{
query:function(){return null;}
},
.state('starred',{
url:'/users/:userId/starred',
template: '<main query="$resolve.query"></main>',
resolve:{
query:function($stateParams){
return {stars:$stateParams.userId};
}
}
})
.state('users',{
url:'/users/:userId',
template: '<main query="$resolve.query"></main>',
resolve:{
query:function($stateParams){
return {user:$stateParams.userId}
}
}
The following are the codes for the controller/component.
class MainController {
constructor($http, $scope, socket, Auth, query) {
this.$http = $http;
this.socket = socket;
this.awesomeThings = [];
$scope.isLoggedIn = Auth.isLoggedIn;
$scope.getCurrentUser = Auth.getCurrentUser;
$onInit() {
this.$http.get('/api/things',{params:{query:query}})
.then(response => {
this.awesomeThings = response.data;
this.socket.syncUpdates('thing', this.awesomeThings);
});
}////////
////////////////////////////////////// etc..
angular.module('paizaApp')
.component('main', {
templateUrl: 'app/main/main.html',
bindings:{query:'='},
controller: MainController
});
I am getting an error message - unknown query provider. However if I remove query from the constructor then the error message is "query is not defined".
Can you please see where I have gone wrong and whether I am supposed to inject the "query" variable into the controller? I am new to Angular 1, not to mention Angular 2.
Update: I have also tried something like this but didn't work:
angular.module('paizaApp')
.config(function($stateProvider) {
$stateProvider
.state('main', {
url: '/',
template: '<main></main>',
resolve:{
query:function(){return null;}
},
controller:function($scope,query){
$scope.query=query
}
And:
angular.module('paizaApp')
.component('main', {
templateUrl: 'app/main/main.html',
controller: MainController,
scope:{query:'='}
});

You shouldn't inject query on controller constructor. You could have do that if you have specified MyController as controller for state.
The query resolve is already passed in component bindings. You can directly get the value of query resolve inside this.query

Related

How can I get ui-router resolve to work when using ng-controller?

Is it possible to get resolves working when using ng-controller? I prefer to use ng-controller as it allows me access to all 1.6+ life-cycle hooks such as $onDestroy, which I loose when defining the controller on state obj.
Plunker:
https://plnkr.co/edit/2FJ0dGtFQtBtcQ0uVbTi?p=preview
In the example below, the view loaded in 'main' makes the myData available to inject, however in main2 the controller is defined with ng-controller and myData is no longer available to inject.
$stateProvider.state('home', {
url: '/',
views: {
'main': {
controller: 'MainCtrl',
controllerAs: 'vm',
templateUrl: 'main.html'
},
'main2': {
templateUrl: 'main2.html'
}
},
resolve: {
myData: function() {
return ['My', 'resolve', 'is', 'working'];
}
}
});
Instantiated with ui-router state:
app.controller('MainCtrl', function(myData) {
console.log("MainCtrl")
console.log(myData);
console.log(this);
this.message = myData.join(' ');
});
Instatiated with ng-controller:
app.controller('MainCtrl2', function($scope) {
console.log("MainCtrl2");
console.log($scope);
this.message = $scope.$resolve.myData.join(' ');
});
The DEMO on PLNKR.

angular-ui: how to get data from "resolve" option when using $stateProvider.state

The docs and stuff I've seen show how to use the "resolve" option but how do you get the data back?
I'm using meanjs.org v0.3.x
My route:
//Setting up route
angular.module('mymodule').config(['$stateProvider',
function($stateProvider) {
//start routing
$stateProvider.
state('some-path', {
url: '/some-url',
templateUrl: 'modules/mymodule/views/my-controller.client.view.html',
resolve: {
DataService: 'DataService',
promiseToResolve: function(DataService){
return DataService.get({});
}
}
});
}
]);
Now how exactly to I access the "promiseToResolve" data in my controller? Docs don't seem to mention this.
Also, please let me know if the above code would break when it is minified.
angular.module('mymodule').config(['$stateProvider',
function($stateProvider) {
//start routing
$stateProvider.
state('some-path', {
url: '/some-url',
templateUrl: 'modules/mymodule/views/my-controller.client.view.html',
controller: mySpecialController,
resolve: {
promiseToResolve: ['DataService', function(DataService) {
return DataService.get({});
}]
}
});
}
]);
You don't need the specific DataService line, so it's removed, and now in your controller (which you've specified in the above code) you can directly access the resolved data:
angular.module('mymodule').controller('mySpecialController', ['$scope', 'promiseToResolve',
function ($scope, promiseToResolve) {
$scope.dataResults = promiseToResolve.data;
}
]);
As for minification, here we use ngInject which is great.

Testing values returned from resolve object in ui-router state

I have a UI-router state with some resolves, and I now want to test the output of these resolves, but I have no idea how to get access to the results.
I tried mocking the controller and check the arguments passed into it, but I seem to be unable to do this.
route:
$stateProvider.state('home', {
url: '/',
views: {
content: {
controller: 'HomeCtrl as vm',
template: ''
}
},
resolve: {
myresolve: function() { return 'cool!'; }
}
});
test:
$state.go('home');
$rootScope.$apply();
expect(???).toEqual('cool!');
In your controller HomeCtrl inject myresolve :
angular.module(...).controlle('HomeCtrl', function(myresolve){
expect(myresolve).toEqual('cool!');
});
cf : https://github.com/angular-ui/ui-router/wiki#resolve
or : https://scotch.io/tutorials/making-skinny-angularjs-controllers#use-ui-router-to-state-the-obvious-

Using $state in ui-router gives

This one is baffling; I'm trying to use the simple $state.go() function in my app which uses ui-router, but I get this:
Uncaught Error: [$injector:modulerr] Failed to instantiate module MainApp due to:
Error: [$injector:modulerr] Failed to instantiate module GroupApp due to:
Error: [$injector:unpr] Unknown provider: $state
http://errors.angularjs.org/1.4.3/$injector/unpr?p0=%24state
at REGEX_STRING_REGEXP
Here is the code I am using:
var app = angular.module('GroupApp', ['ui.router']);
groupjs_config.$inject = ['$stateProvider', '$state', '$urlRouterProvider'];
app.config(groupjs_config);
groupjs_controller.$inject = ['$scope'];
app.controller('groupjs.ctrl', groupjs_controller);
//----------------------------------------------------
// FUNCTIONS
//----------------------------------------------------
function groupjs_config($stateProvider, $state, $urlRouterProvider){
// For any unmatched url, redirect to /state1
$stateProvider
.state('group', {
abstract: true,
url: "/group/:groupid",
onEnter: function(){
if (true){ //logged in
$state.go('group.home');
}
else {
$state.go('group.noaccess');
}
}
})
.state('group.home', {
url: "/group/:groupid",
templateUrl: "groups/group/group.html"
})
.state('group.noaccess', {
url: "/group/:groupid",
templateUrl: "groups/group/group_noaccess.html"
});
}
function groupjs_controller($scope){
$scope.hi = "hi";
$.material.checkbox('mycheckbox');
$scope.groups = [
];
}
Try injecting the $state to the onEnter method :
onEnter: ['$state',function($state){
if (true){ //logged in
$state.go('group.home');
}
else {
$state.go('group.noaccess');
}
}]
and take it out from the config:
groupjs_config.$inject = ['$stateProvider', '$urlRouterProvider'];
...
function groupjs_config($stateProvider, $urlRouterProvider){
Only providers and constants can be injected into config blocks see the table at the bottom of https://docs.angularjs.org/guide/providers
The $state can be injected into the controller, or any filter, factory, service, run block etc. but just not in config. In order for anything but a provider to be created it must first have been configured (this is what the config blocks are for, configuring providers of services/factories/values).
First change this line:
groupjs_config.$inject = ['$stateProvider', '$state', '$urlRouterProvider'];
to:
groupjs_config.$inject = ['$stateProvider', '$urlRouterProvider'];
Change your routing function like this:
function groupjs_config($stateProvider, $urlRouterProvider){
// For any unmatched url, redirect to /state1
$stateProvider
.state('group', {
abstract: true,
url: "/group/:groupid",
onEnter: ['$state',function($state){
if (true){ //logged in
$state.go('group.home');
}
else {
$state.go('group.noaccess');
}
}]
})
.state('group.home', {
url: "/group/:groupid",
templateUrl: "groups/group/group.html"
})
.state('group.noaccess', {
url: "/group/:groupid",
templateUrl: "groups/group/group_noaccess.html"
});
}
ui-router
$stateProvider
.state('admin', {
abstract: true,
url: '/admin',
template: '<div ui-view></div>'
})
.state('admin.index', {
url: '/index',
template: '<h3>Admin index</h3>'
})
.state('admin.users', {
url: '/users',
template: '<ul>...</ul>'
});
onEnter, onExit
Our app calls these callbacks when we transition into or out of a view. For both options, we can set a function we want called; these functions have access to the resolved data.
These callbacks give us the ability to trigger an action on a new view or before we head out to another state. It’s a good way to launch an “Are you sure?” modal view or request the user log in before they head into this state.

TypeError: Cannot read property 'open' of undefined

I am trying to create a POP UP using a Modal in angular js.I am facing and issue.Its says.
TypeError: Cannot read property 'open' of undefined.
Its throwing at $modal.open statement.
The code for config as below :
homeModuleApp.config(function ($stateProvider) {
$stateProvider.state('login', {
url: '/login',
//templateUrl: '/app/ng/modules/home/partials/login-partials-view.html',
//controller: 'ModalDemoCtrl'
onEnter: function($stateParams, $state, $modal) {
$modal.open({
templateUrl: '/app/ng/modules/home/partials/login-partials-view.html',
resolve: {},
controller: 'ModalDemoCtrl'
}).result.then(function (result) {
// $scope.$close
alert('result ->' + result);
}, function (result) {
// $scope.$dismiss
alert('dismiss ->' + result);
}).finally(function () {
// handle finally
console.log('Hello....');
});
}
})
});
Can anyone guide me what could be the issue?
Thanks
So, here I've put together a jsBin which demonstrates how to do this with your code.
You can't use the $modal service in your .config section, as services are not available at that state of Angular bootstrapping (perhaps some $modalProvider is, but I'm not sure). So, you can set the state up to go to some log in page, like:
.config(function($stateProvider) {
$stateProvider
.state('login', {
url: '/',
templateUrl: 'login.html',
controller: 'loginController',
controllerAs: 'vm'
});
})
And then in that controller, you can use an immediately invoked function expression (IIFE) to trigger as soon as the controller is loaded, which will include your $modal.open code, like:
.controller('loginController', function($modal) {
(function() {
$modal.open({
templateUrl: 'loginModal.html',
controller: 'loginModalController',
controllerAs: 'vm'
}).result.then(function (result) {
alert('result ->' + result);
}, function (result) {
alert('dismiss ->' + result);
}).finally(function () {
console.log('Hello....');
});
})();
One solution could be the injection of MatDialog into the constructor like:
constructor(
public router: Router,
public dialog: MatDialog
)

Resources