I am attempting to have DRY states with UI-Router. I have a page service AlchemyPage which fetches a page through the API using $http.get
This works perfectly when I use it with an inline controller:
$stateProvider.state('home', {
url: '/',
controller: function($stateParams, $scope, AlchemyPage) {
AlchemyPage.load($stateParams, $scope);
}
});
$stateProvider.state('organization', {
url: '/package-organization/:page',
templateUrl: 'alchemy/page.html',
controller: function($stateParams, $scope, AlchemyPage) {
$scope.org = true;
AlchemyPage.load($stateParams, $scope);
}
});
I attempted to get rid of repetition and created a controller:
angular.module('App').controller('MainPageCtrl', [
'$scope',
'$stateParams',
'isOrganization',
'AlchemyPage',
function($scope,
$stateParams,
isOrganization,
AlchemyPage) {
$scope.org = isOrganization;
AlchemyPage.load($stateParams,$scope);
}
]);
However, when I implemented as below, the controller does not get called.
$stateProvider.state('home', {
url: '/',
templateUrl: 'alchemy/home.html',
controller: 'MainPageCtrl',
resolve: {
isOrganization: 'false'
}
});
$stateProvider.state('organization', {
url: '/package-organization/:page',
templateUrl: 'alchemy/page.html',
controller: 'MainPageCtrl',
resolve: {
isOrganization: 'true'
}
});
Using AngularJS v.1.6.4
Using UI-Router v.0.4.2
I resolved this issue by using params instead of resolve
Modified 'home' state:
$stateProvider.state('home', {
url: '/',
templateUrl: 'alchemy/home.html',
controller: 'MainPageCtrl'
});
The below resolve object no longer needed in either state due to changing logic in AlchemyPage resource:
resolve: {
isOrganization: 'false'
}
Revised state for organization:
$stateProvider.state('organization', {
url: '/package-organization/:page',
templateUrl: 'alchemy/page.html',
controller: 'MainPageCtrl',
params: {
topic: 'organization'
}
});
You can see in the above that the flag is now set for organization by passing in
params: {
topic: 'organization'
}
So here is the cleaned up controller:
App.controller('MainPagedCtrl', [
'$stateParams',
'$scope',
'AlchemyPage',
function($stateParams,
$scope,
AlchemyPage) {
AlchemyPage.load($stateParams,
$scope);
}
]);
With the above corrections, the named controller works properly. Resolve does work as expected, I was just using it improperly.
Related
I have a Nuxtjs app which authenticates fine. But I need the user details for filling out a form automatically. I see that the app calls /user endpoint on every reload. I want to insert a $store in its callback to store the user data in $store.
computed: {
getUser () {
return this.$store.state.user.user;
}
},
methods: {
setUser (data) {
this.$store.commit('user/add', data)
},
}
NUXT Config:
auth: {
strategies: {
local: {
endpoints: {
login: {
url: '/auth/login',
method: 'post',
propertyName: 'access_token'
},
logout: {
url: '/auth/logout',
method: 'post'
},
user: {
url: '/auth/user',
method: 'get',
propertyName: false
},
tokenRequired: true
}
}
}
}
Is it possible to intercept the $auth.fetchUser or whatever method $auth is using to fetch the api/user endpoint on every reload?
I solved it by using auth and vuex methods. I don't need to intercept the call. Just use
this.$auth.user
or
this.$store.state.auth.user;
Learning Nuxt/Vuejs is fun.
I'm having trouble understanding nested views in UI Router nested views... more specifically what they look like...?
I need to understand it because I need my $scope property to be inherited.
I see this example in the docs
$stateProvider
.state('contacts', {
abstract: true,
url: '/contacts',
templateUrl: 'contacts.html',
controller: function($scope){
$scope.contacts = [{ id:0, name: "Alice" }, { id:1, name: "Bob" }];
}
})
.state('contacts.list', {
url: '/list',
templateUrl: 'contacts.list.html'
})
.state('contacts.detail', {
url: '/:id',
templateUrl: 'contacts.detail.html',
controller: function($scope, $stateParams){
$scope.person = $scope.contacts[$stateParams.id];
}
})
Then I see something like this in the docs
$stateProvider
.state('report',{
views: {
'filters': {
templateUrl: 'report-filters.html',
controller: function($scope){ ... controller stuff just for filters view ... }
},
'tabledata': {
templateUrl: 'report-table.html',
controller: function($scope){ ... controller stuff just for tabledata view ... }
},
'graph': {
templateUrl: 'report-graph.html',
controller: function($scope){ ... controller stuff just for graph view ... }
}
}
})
Its all a bit confusing to me and since I need $scope inheritance I need to nest my views - just not quite sure which example that it it.
UPDATE
Here are my states
$locationProvider.html5Mode(false);
$stateProvider
.state('search', {
abstract: true,
url: '/search',
controller: 'searchCtrl',
controllerAs: 'vm',
templateUrl: 'search/index.html'
})
.state('search.query', {
url: '/',
controller: 'searchCtrl',
controllerAs: 'vm',
templateUrl: 'search/query.html'
})
.state('search.results', {
url: '/?q',//for query parameter in url
controller: 'searchCtrl',
controllerAs: 'vm',
templateUrl: 'search/results.html'
});
$urlRouterProvider.otherwise('/');
What I'm trying to achieve with this is just a simple search form on query.html, once a user enters or selects a search term then it goes to search.html with another search form and results.
These are my templates, I believe I have them set up correctly but something is wrong because nothing displays.
/app/index.html
<div ui-view></div>
/app/search/index.html
<div ui-view></div>
/app/search/query.html
<form>
...
</form>
/app/search/results.html
<div ui-view></div>
<div>
...
</div>
First one is an example of a nested state which fulfills your requirement for inheriting the scope object. e.g state/sub-state-a, state/sub-state-b
The comment above the first snippet you took from the doc reads:
Shows prepended url, inserted template, paired controller, and
inherited $scope object.
The second example is a nested view where you can define multiple views per state and use each depending on your use-case.
From the docs:
Then each view in views can set up its own templates (template,
templateUrl, templateProvider), controllers (controller,
controllerProvider).
How can I retrieve json in Vuejs in vue.js in laravel 4?
I tried following but it didn't work:
new Vue({
el: '#guestbook',
data: {
comments: [],
text: '',
author: ''
},
ready: function() {
this.getMessages();
},
methods: {
getMessages: function() {
$.ajax({
context: this,
url: "/cms/Getweb_manager",
success: function (result) {
this.$set("comments", result)
}
})
}
}
})
Have you tried logging the response? Just use a console.log(result).
About your doubt, you probably have to do this.$set('comments', result.data');.
Don't forget the semicolon!
Have a look at the vue-resource package
https://github.com/vuejs/vue-resource
It should work like this
methods: {
getMessages: function() {
this.$http({
url: '/cms/Getweb_manager',
method: 'GET'
}).then(function (response) {
// success callback
this.$set('comments', response.result);
}, function (response) {
// error callback
});
}
}
Route:
Here template and controller is not working. Below is code:
(function() {
'use strict';
angular.module('signup', ['ui.router']).config(appConfig);
appConfig.$inject = ['$stateProvider', '$locationProvider'];
function appConfig($stateProvider, $locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: true
});
$stateProvider
.state('signup', {
url: '/',
templateUrl: 'app/signup/signup.html',
controller: 'SignUpController',
controllerAs: 'vm'
});
}
})();
Controller:
(function() {
'use strict';
angular
.module('signup')
.controller('SignUpController', SignUpController);
function SignUpController() {
var vm = this;
vm.title = "signup";
console.log("signup controller");
}
})();
HTML here
<h1>{{vm.title}}</h1>
console and title is not displaying. I don't know what is wrong here.
Thank you
The issue was probably the absence of tag, which is required by angular ui-router to insert any template associated to a state.
Adding the same solved the issue.
Is there a better way to redirect through a state without using $urlRouterProvider? I want to redirect to elsewhere after going through the base.home state.
$stateProvider
.state('base', {
url: '/base',
abstract: true,
views: {
"mainbase": {
templateUrl: 'ng/apps/base/views/header.html',
controller: 'HeaderCtrl'
}
},
})
.state('base.home', {
url: '',
views: {
"baseHeaderView": {
template: 'base home, you should not be here',
controller: function($state) {
// Can this be accomplished better?
$state.go('base.elsewhere');
}
}
}
})
.state('base.elsewhere',{
url: '/elsewhere'
//I want to redirect to here after going through the base.home state
});
Mark your redirect state with an attribute, then add a global listener for $stateChangeStart and conditionally supersede the transition.
This does the redirection in place of the original transition, so 'base.home' isn't even activated temporarily. If you
app.run($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function(evt, toState, params) {
if (toState.redirectTo) {
evt.preventDefault();
$state.go(toState.redirectTo, params);
}
});
}
app.config(function($stateProvider) {
$stateProvider.state('base', {
url: '/base',
abstract: true,
views: {
"mainbase": {
templateUrl: 'ng/apps/base/views/header.html',
controller: 'HeaderCtrl'
}
},
})
.state('base.home', {
url: '',
views: {
"baseHeaderView": {
template: 'base home, you should not be here',
controller: function($state) {
// Can this be accomplished better?
$state.go('base.elsewhere');
}
}
},
redirectTo: 'base.elsewhere'
})
.state('base.elsewhere',{
url: '/elsewhere'
//I want to redirect to here after going through the base.home state
});
});