I'm using angular ui-router and need to show a different template for a given state based on a variable in the parent (body) scope. But when I add this $scope.data conditional it doesn't fire. I don't even get the console.log() or any url change. :(
$stateProvider.state('map1', {
url: "/content/sectionI",
templateProvider: function($scope, $http, $stateParams) {
console.log("Wowie!",$scope.data);
if($scope.data.Section_I_Part_1_Complete == "0")
{
return $http({
method: 'GET',
url: 'http://example.com/contentMore',
params: {
request: "Section_I_Part_1_Complete",
part: "1"
}
}).then(function successCallback(html) {
return html.data;
});
}
else
{
return $http({
method: 'GET',
url: 'http://example.com/contentMore',
params: {
request: "Section_I_Unlocked",
part: "map"
}
}).then(function successCallback(html) {
return html.data;
});
}
},
controller: function($scope) {
$scope.activeSection.activeSection = "notNone";
}
})
How do I do it so that I can get the template to return based on the value of a variable in the parent scope?
Just use a service to store the data and inject that service.
templateProvider: function(myDataService) {
var part = myDataService.Section_I_Part_1_Complete == "0" ? 1 : 'map';
return $http.get('http://example.com/contentMore', {
params: {
request: "Section_I_Part_1_Complete",
part: part
}
}).then(function(response) {
return response.data;
});
}
Related
I'm trying to call a function from a service in a controller but I get an error saying that the thing I'm calling isn't a function. I'm new to AngularJS so I'm not exactly sure what I'm doing wrong. So, what's the correct way to call a service function in a controller?
I'm trying to call getCurrentUserInfo in the ProfileCtrl
.service('AuthService', function($http, Backand){
function getCurrentUserInfo() {
return $http({
method: 'GET',
url: baseUrl + "users",
params: {
filter: JSON.stringify([{
fieldName: "email",
operator: "contains",
value: self.currentUser.name
}])
}
}).then(function (response) {
if (response.data && response.data.data && response.data.data.length == 1)
return response.data.data[0];
});
}
})
.controller('ProfileCtrl', ['$scope', '$ionicSideMenuDelegate', 'AuthService', function($scope, $ionicSideMenuDelegate, AuthService) {
AuthService.getCurrentUserInfo().then(function(response){
$scope.user = response.data.data;
});
// function getCurrentUserInfo() {
// AuthService.getCurrentUserInfo()
// .then(function (result) {
// $scope.user = result.data;
// });
// }
}])
You need to make it a property of this.
.service('AuthService', function($http, Backand){
this.getCurrentUserInfo = function() {
return $http({
method: 'GET',
url: baseUrl + "users",
params: {
filter: JSON.stringify([{
fieldName: "email",
operator: "contains",
value: self.currentUser.name
}])
}
}).then(function (response) {
if (response.data && response.data.data && response.data.data.length == 1)
return response.data.data[0];
});
}
})
Then in your controller
AuthService.getCurrentUserInfo(whatEverYourParamsAre)
Edit: Actually, let me provide a little bit of context. Angular applies the new function to every .service(....) you include in your controller. As we know, calling this.aFunction in a constructor function causes the new operator in javascript to treat the aFunction function as a property on the object your constructor returns.
I'm having an issue loading a child view/route while resolving a GET from a different service from the parent view/route.
Within the parent view, each ion-item links to /#/tab/categories/{{ category.listing_category_id }}
When clicked the URL populates (for a flash) with the correct category ID, the child's service successfully receives the category ID, runs the subsequent GET request & returns the data as a promise...that all works as intended. The issue is that the child view/route never loads. All help/guidance is very much appreciated.
Parent
angular.module('rainbowPages.tab.categories', [])
.config(function($stateProvider, $urlRouterProvider) {
// UI Router
$stateProvider.state('tab.categories', {
url: '/categories',
views: {
'tab-categories': {
templateUrl: 'views/tab-categories/tab-categories.html',
controller: 'CategoriesCtrl'
}
}
});
// otherwise
$urlRouterProvider.otherwise('/tab/categories');
})
.factory('CategoriesService', function($resource) {
var remoteCategoriesURL = 'http://104.167.104.163:7000/api/v1/categories',
categoriesService = $resource(remoteCategoriesURL, {}, {
getAll: {
method: 'GET',
isArray: true
}
});
return categoriesService;
})
.controller('CategoriesCtrl', function($scope, CategoriesService) {
$scope.categories = CategoriesService.getAll();
});
Child
angular.module('rainbowPages.tab.categories.detail', [])
.config(function($stateProvider, $urlRouterProvider) {
// UI Router
$stateProvider.state('tab.category-detail', {
url: '/categories/:listing_category_id',
views: {
'tab-categories': {
templateUrl: 'views/category-detail/category-detail.html',
controller: 'categoryDetailCtrl'
}
},
resolve: {
listings: function($stateParams, CategoryDetailService) {
// bind data to listing
return CategoryDetailService($stateParams.listing_category_id);
}
}
});
})
.factory('CategoryDetailService', function($resource) {
var remoteCategoryURL = 'http://104.167.104.163:7000/api/v1/category/:categoryID',
categoryDetailService = $resource(remoteCategoryURL, {categoryID:'#listing_category_id'}, {
get: {
method: 'GET',
isArray: true
}
}),
getListingsInCategory = function getListingsInCategory(categoryID) {
listingsInCategory = categoryDetailService.get({categoryID:categoryID}, function(promise) {
if(promise.$resolved = true) {
console.log(promise); // how I know the promise has the correct data
return promise;
}
});
};
return getListingsInCategory;
})
.controller('categoryDetailCtrl', function($scope, listings){
console.log('listings are : ' + listings);
$scope.listings = listings;
});
I have this Angular code:
.state('UserTables', {
url: '/Tables',
resolve: {
auth: function resolveAuthentication(SessionService) {
return SessionService.isUser();
}
},
views: {
"containerMain": {
templateUrl: 'Views/Tables',
controller: TableController
},
}
})
And would like to pass some request header to the templateUrl call.
Anyone done something like that?
Basically I have a REST service that can generate the view I need depending on 1 header and some property's. Property's are no problem but I have no clue how to make a call to the service and wait for the result.
Tried:
views: {
"containerMain": {
template: function (SessionService, $http, $q) {
console.log('template');
var resp = SessionService.getTable($http, $q, 'Generate/Table?objectId=WfObject');
var r = '';
resp.then(function (result) {
r = result;
console.log('resp:', r);
});
console.log('r:',r);
return r;
}
I created working plunker here
To load template with custom headers, we can call do it like this (check the state 'UserTables' in the plunker):
views: {
"containerMain": {
//templateUrl: 'Views/Tables',
templateProvider: ['$http',
function ($http) {
var tplRequest = {
method: 'GET',
url: 'Generate/Table?objectId=WfObject',
headers: {
'MyHeaderKey': 'MyHeaderValue'
},
}
return $http(tplRequest)
.then(function(response) {
console.log('loaded with custom headers')
var tpl = response.data;
return tpl;
}
);
}],
controller: 'TableController'
},
}
In case, we want (and can) cache the template, we can do it like this (check the state 'UserTablesWithCache'):
views: {
"containerMain": {
//templateUrl: 'Views/Tables',
templateProvider: ['$http', '$templateCache',
function ($http, $templateCache) {
var templateName = 'Generate/Table?objectId=WfObject';
var tpl = $templateCache.get(templateName)
if(tpl){
console.log('returning from cache');
return tpl;
}
var tplRequest = {
method: 'GET',
url: templateName,
headers: {
'MyHeaderKey': 'MyHeaderValue'
},
}
return $http(tplRequest)
.then(function(response) {
console.log('loaded, placing into cache');
var tpl = response.data;
$templateCache.put(templateName, tpl)
return tpl;
}
);
}],
controller: 'TableController'
},
}
And if we would not need headers, and we could cache, it is really very easy, as documented here:
Trying to Dynamically set a templateUrl in controller based on constant
Drafted version could be: (no custom headers but effective loading and caching)
templateProvider: ['$templateRequest', function(CONFIG, $templateRequest) {
var templateName = 'Generate/Table?objectId=WfObject';
return $templateRequest(templateName);
}],
templateUrl property can also take function as value. So you can add dynamic properties to the templateUrl via there.
templateUrl : function(stateParams) {
// before returning the URL, add additional properties and send
// stateParamsargument object refers to $stateParams and you can access any url params from there.
return 'Views/Tables';
}
How can i get "pageid" inside resolve block?
For every url change i had to request the server, along with the "pageid"?
My code:
app.config(function($routeProvider){
$routeProvider
.when('/mainpage/:pageid',
{
controller:'ContentController',
resolve: {
data: function ($q, $http) {
console.log(window.location.hash)
var deferred = $q.defer();
$http({method: 'GET', url: mainURL}).then(function(data) {
deferred.resolve(data);
});
return deferred.promise;
}
},
templateUrl : 'app/partials/masterTemplate.html'
})
.otherwise({redirectTo:'/mainpage/home'});
});
You can do it like this:
data: function ($http, $routeParams) {
return $http({
method: 'GET',
url: mainURL,
params: {
pageid: $routeParams.pageid
}
})
.then(function(data) {
return data;
});
}
Consider the code:
var myApp = angular.module('myApp', []);
The routes:
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'app.html',
controller:myAppController,
resolve:{
resolveData:function(Resolver){
return Resolver();
}
}
});
});
Resolve:
myApp.factory('Resolver', ['$http', function($http){
return function(){
return $http({url: '/someurl',method: "GET"}).then(function(data) {
// dependent call 1
$http({url: '/someotherurl',method: "GET" }).then(function(data) {
});
// dependent call 2
$http({url: '/someanotherurl',method: "GET" }).then(function(data) {
});
});
}
}]);
Above I have nested 2 calls inside one as they are dependent on the data returned by the parent call.
What I want to do: return the Resolver when all of them have completed and not just the parent call.
I cannot use $q.all() because 2 of the calls are dependent of the first call.
In short, myAppController must be loaded only after all the 3 calls have completed.
You should be using chaining promise and $q service to solve your problem .Just use the below sample code it should work
myApp.factory('Resolver', ['$http','$q', function ($http,$q) {
return function () {
var deferred = $q.defer();
$http({ url: '/someurl', method: "GET" }).then(function (data) {
return $http({ url: '/someurl', method: "GET" })
}).then(function (data) {
return $http({ url: '/someanotherurl', method: "GET" })
}).then(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
}]);
This works for me:
resolve : {
message: function($q, $route, Restangular) {
var msgId = $route.current.params.msgId;
var deferred = $q.defer();
Restangular.one('message', msgId).get().then(function(message) {
Restangular.one('file', message.audioFile.id).get().then(function (blob) {
message.blob = blob;
deferred.resolve(message);
});
});
return deferred.promise;
}
}