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;
});
}
Related
Component:
crudModule.js
var crudModule = angular.module('crudModule', ['ui.router', 'smart-table', 'ngCookies', 'ui.bootstrap', 'angularModalService', 'dialogs', 'remoteValidation']);
angular.module('crudModule').component('applicationInfo', {
templateUrl: 'infoApplication.html',
controller: 'applicationInfoCtrl'
});
applicationInfoCtrl.js:
var crudModule = angular.module('crudModule')
crudModule.controller('applicationInfoCtrl', ['httpService', '$scope', function($http, $scope, $cookies, $stateParams, httpService) {
httpService.httpGetRequest("http://localhost:8080/applications/" + $stateParams.id).then(function success(response) {
$scope.application = response.data;
});
$scope.getApiKey = function () {
httpService.httpGetRequest('http://localhost:8080/applications/generateApiKey').then(function success(response) {
$scope.application.apikey = response.data.apikey;
$scope.application.apisecret = response.data.apisecret
})
};
$scope.send = function (object, url) {
httpService.httpPostRequest(object, url + "/" + $stateParams.id).catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
}).then(function success(response){
});
}
}]);
httpService.js:
var crudModule = angular.module('crudModule')
crudModule.factory('httpService', function($http) {
return {
httpGetRequest: function (url) {
return $http({
method: 'GET',
url: url
})
},
httpPostRequest: function (object, url){
return $http({
method:'POST',
url: url,
data: object
})
}
}
});
I am getting error:
Cannot read property 'httpGetRequest' of undefined.
I have injected my httpService and i dont find any mistakes yet
The problem is the order of parameters in your controller, it should be
crudModule.controller('applicationInfoCtrl', ['$http','httpService', '$scope','$cookies','$stateParams' function(http,httpService, $scope,$cookies,$stateParams) {
}
I have 2 factories: ApiService and LocationService.
In ApiService i'd like to return the endpoint from an $http call that LocationService will use.
But it seems when the controller calls LocationService, it doesn't wait for the response from ApiService. Here is some snippet of code, in ApiService when I finally get it working I will cache it so I won't need to make a server call each time to get the endpoint:
services.factory("ApiService", ["$location", "$http", function ($location, $http) {
return {
getEndpointUrl: function () {
var endpoint;
$http({
method: 'GET',
url: '/site/apiendpoint'
}).then(function successCallback(response) {
endpoint = response.data;
console.log(endpoint);
return endpoint;
}, function errorCallback(response) {
console.error('Error retrieving API endpoint');
});
}
}
}]);
Here is the location service, it consumes ApiService:
services.factory("LocationService", ["$resource", "ApiService", function ($resource, apiService) {
var baseUri = apiService.getEndpointUrl();
return $resource(baseUri + '/location', {}, {
usStates: { method: 'GET', url: baseUri + '/location/us/states' }
});
}]);
When my controller tries to call LocationService.usStates the baseUri is undefined. What am I doing wrong here?
The reason is because your getEndpointUrl function is asynchronous, and it has no return value.
Since your LocationService uses $resource and depends on on the baseUri, I would suggest bootstrapping that data along with the initial page load and making it a constant like:
angular.module('yourModule').constant('baseUrl', window.baseUrl);
Then your service would inject it to create your resource:
services.factory("LocationService", ["$resource", "ApiService", "baseUrl", function ($resource, apiService, baseUrl) {
return $resource(baseUrl + '/location', {}, {
usStates: { method: 'GET', url: baseUrl + '/location/us/states' }
});
}]);
In ApiService, you're not actually returning a value from getEndpointUrl(). How about you return a promise from ApiService, and then consume that in LocationService in a synchronous fashion?
services.factory("ApiService", ["$location", "$http", function($location, $http) {
return {
getEndpointUrl: function() {
var endpoint;
return $http({
method: 'GET',
url: '/site/apiendpoint'
});
}
}
}]);
services.factory("LocationService", ["$resource", "ApiService", function($resource, apiService) {
return {
getLocations: function() {
return apiService.getEndpointUrl().then(function successCallback(response) {
var baseUri = response.data;
return $resource(baseUri + '/location', {}, {
usStates: { method: 'GET', url: baseUri + '/location/us/states' }
});
}, function errorCallback(response) {
console.error('Error retrieving API endpoint');
});
}
};
}]);
And then in your controller:
LocationService.getLocations().then(function(data) {
$scope.statesResult = data.result.states;
});
I'm not quite sure what I'm doing wrong, but it seems that my profile doesn't resolve by the time we get to the MainCtrl. The user however does, resolve. Am I, perhaps not fetching the profile information properly in the Auth Service?
Router:
angular.module('app')
.config(function ($stateProvide) {
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'app/main/main',
controller: 'MainCtrl',
resolve: {
user: function (Auth) {
return Auth.getUser();
},
profile: function (user) {
return Auth.getProfile();
}
}
});
});
Controller:
angular.module('app')
.controller('MainCtrl', function ($scope, user, profile) {
$scope.user = user;
$scope.profile = profile; <- DOESNT RESOLVE
});
Auth Service:
angular.module('app')
.factory('Auth', function ($firebaseSimpleLogin, $firebase, FBURL) {
var ref = new Firebase(FBURL);
var auth = $firebaseSimpleLogin(ref);
var Auth = {
user: {},
getUser: function () {
return auth.$getCurrentUser();
},
getProfile: function(uid) {
return $firebase(ref.child('users').child(uid)).$asObject();
}
};
return Auth;
});
Something like
auth.$getCurrentUser()
returns a promise so you need a
.then(function(user) {
event before your callback complete
In your case you may just resolve on the then, something like
Auth.getUser().then(function(user){ return user; });
Also $asObject() needs $loaded() for it's promise
var obj = $firebase(ref).$asObject();
obj.$loaded()
.then(function(data) {})
Try this structure for your promises:
var fetchSomething = function (action, params) {
var promise = $http({
method: 'POST',
url: 'someurl to the firebase',
data: params,
headers: {
'Access-Control-Allow-Origin': true,
'Content-Type': 'application/json'
}
}).success(function (data, status, headers, config) {
return data;
});
return promise;
};
My problem is that I have a $scope.page on to different controllers under the same module.
the $scope.page data should change for each route.
I'm trying to understand this...
some code:
hall.config(function ($routeProvider) {
$routeProvider.when("/", { controller: 'pageForsideController', templateUrl: "pages/forside.html" })
.when("/om", { controller: 'pageOmController', templateUrl: "pages/omMig.html" })
.otherwise({ redirectTo: '/' })
});
hall.controller('pageOmController', function ($scope, siteData) {
siteData.getServices(function (data) {
$scope.services = data;
})
siteData.getPageByName("Mig", function (data) {
$scope.page = data;
});
});
hall.controller('pageForsideController', function ($scope, siteData) {
siteData.getPageByName("Forside", function (data) {
$scope.page = data;
});
});
hall.factory("siteData", function ($http) {
return {
getServices: function (successcb) {
$http({ method: 'GET', url: 'data.json' })
.success(function (data, status, headers, confic) {
successcb(data.services);
console.log("getServices")
});
},
getPageByName: function (name, successcb) {
$http({ method: 'GET', url: 'data.json' })
.success(function (data, status, headers, confic) {
for (var i = 0; i < data.pages.length; i++)
if (data.pages[i].title == name)
successcb(data.pages[i]);
});
}
}
});
Updated:
here is a plunker
http://plnkr.co/edit/9K3C3ahi5WMPeKLeL318?p=preview
The OP fixed the problem by following charlieftl's instructions, and removing the controller from either markup or $routeProvider.
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;
}
}