I have an angular app that needs to do a quick http request to get some config information before the rest of the application is initiated, at least before the controllers. Looked into using $UrlRouterProvider, but I did not figure out how to make the app wait for the http be done.
What I need to be finished:
$http({method: 'GET', url: '/config'}).then(function(res) {
configProvider.setConfig(res.data.config);
}
You can create a separate js file where you can make http request and then initialize/bootstrap your app via js code instead of ng-app in html code.
Refer the below code:
(function() {
var application, bootstrapApplication, fetchData;
application = angular.module('app');
fetchData = function() {
var $http, initInjector;
initInjector = angular.injector(['ng']);
$http = initInjector.get('$http');
$http.get('<url>');
};
bootstrapApplication = function() {
angular.element(document).ready(function() {
angular.bootstrap(document, ['app']);
});
};
fetchData().then(bootstrapApplication);
})();
I hope it helps.
Resolve must be declared on state, not on the view
change
.state('app', {
abstract: true,
url:'/',
views: {
"content": {
templateUrl: "myurl.html"
},
resolve {
myVar: ['$http', 'myService', function($http, myService) {
return $http({method: 'GET', url:'url'})
.then(function(res) { //do stuff })
to
.state('app', {
abstract: true,
url:'/',
views: {
"content": {
templateUrl: "myurl.html"
}
},
resolve {
myVar: ['$http', 'myService', function($http, myService) {
return $http({method: 'GET', url:'url'})
.then(function(res) { //do stuff })...
Related
I am new in Angular JS and I stack with problem with inject resolve promise to controller.
I have next code:
var app = angular.module('app', ['ui.router', 'ngAnimate', 'ngSanitize', 'ui.bootstrap'])
.config(function ($stateProvider, $urlMatcherFactoryProvider, $urlRouterProvider) {
$urlMatcherFactoryProvider.caseInsensitive(true);
$urlRouterProvider.otherwise('/refuel');
$stateProvider.state('refuels', {
url: '/refuel',
controller: 'refuelController',
controllerAs: 'refuelCtrl',
resolve: {
$refuelsPumpsResolve: function ($http) {
return $http({
url: "http://localhost:60000/Refuels/GetUserPumps",
method: "GET"
})
}
}
})
})
.controller('refuelController', function ($refuelsPumpsResolve) {
var $this = this;
this.isOpen = true;
this.isOpen = function () {
$this.isOpen = !$this.isOpen
}
this.pumpsData = $refuelsPumpsResolve;
});
However angular throws 'Unknown provider' exception for $refuelsPumpsResolve in controller.
I do not see any problem, more over the code was taken from ui-route tutorial on github.
Thanks for help
Try this, declaring the injection as you would normally do for say, a controller:
resolve: {
$refuelsPumpsResolve: ['$http', function ($http) {
return $http({
url: "http://localhost:60000/Refuels/GetUserPumps",
method: "GET"
})
}]
}
Right now i am making an AngularJS+UI router install application. But i have a problem, the problem is, that i want to disable access to the views, associated with the install application. I want to do it in resolve in the state config.
But the problem is i need to get the data from a RESTful API, whether the application is installed or not. I tried making the function, but it loaded the state before the $http.get request was finished.
Here was my code for the resolve function:
(function() {
var app = angular.module('states', []);
app.run(['$rootScope', '$http', function($rootScope, $http) {
$rootScope.$on('$stateChangeStart', function() {
$http.get('/api/v1/getSetupStatus').success(function(res) {
$rootScope.setupdb = res.db_setup;
$rootScope.setupuser = res.user_setup;
});
});
}]);
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/404");
$stateProvider.state('db-install', {
url: "/install/db",
templateUrl: 'admin/js/partials/db-install.html',
controller: 'DBController',
resolve: {
data: function($q, $state, $timeout, $rootScope) {
var setupStatus = $rootScope.setupdb;
var deferred = $q.defer();
$timeout(function() {
if (setupStatus === true) {
$state.go('setup-done');
deferred.reject();
} else {
deferred.resolve();
}
});
return deferred.promise;
}
}
})
.state('user-registration', {
url: "/install/user-registration",
templateUrl: "admin/js/partials/user-registration.html",
controller: "RegisterController"
})
.state('setup-done', {
url: "/install/setup-done",
templateUrl: "admin/js/partials/setup-done.html"
})
.state('404', {
url: "/404",
templateUrl: "admin/js/partials/404.html"
});
}]);
})();
EDIT:
Here is what my ajax call returns:
Try this way:
$stateProvider.state('db-install', {
url: "/install/db",
templateUrl: 'admin/js/partials/db-install.html',
controller: 'DBController',
resolve: {
setupStatus: function($q, $state, $http) {
return $http.get('/api/v1/getSetupStatus').then(function(res) {
if (res.db_setup === true) {
$state.go('setup-done');
return $q.reject();
}
return res;
});
}
}
})
Then inject setupStatus in controller:
.state('setup-done', {
url: "/install/setup-done",
templateUrl: "admin/js/partials/setup-done.html",
controller: ['$scope', 'setupStatus', function ($scope, setupStatus) {
$scope.setupdb = setupStatus.db_setup;
$scope.setupuser = setupStatus.user_setup;
}]
})
I am working with angular.js and satelizer to do JWT Authentication on a REST API.
The authentication works fine and the page is sending the authorization header within 3 states. Here is my state provider:
$stateProvider
.state('auth', {
url: '/auth',
templateUrl: '/views/login.html',
controller: 'AuthController as auth'
})
.state('dashboard', {
url: '/dashboard',
templateUrl: '/views/dashboard.html',
controller: 'DashboardController as dash'
})
.state('mitglieder', {
url: '/mitglieder',
templateUrl: '/views/mitglieder.html',
controller: 'MitgliederController as mitglieder'
})
.state('neuesMitglied', {
url: '/neuesMitglied',
templateUrl: '/views/neuesMitglied.html',
controller: 'NewMitgliederController as newMitglied'
})
.state('users', {
url: '/users',
templateUrl: '/views/main.html',
controller: 'UserController as user'
});
});
But however, inside the state 'neuesMitglied' it suddenly does no longer send the authorization header and gets rejected by the rest api. My NewMitgliederController looks like this:
(function() {
'use strict';
angular
.module('authApp')
.controller('NewMitgliederController', NewMitgliederController);
function NewMitgliederController($auth, $state, $http, $rootScope, $scope) {
var vm = this;
vm.error;
//vm.toAdd;
//vm.rawImage;
//Fetched Data
vm.fetchedData;
var fetchData = function() {
$http.get('APIv1/Beitragsgruppen/list/').success(function (data) {
vm.fetchedData.mitgliedsgruppen = data;
}).error(function (error) {
vm.error = error;
});
}
angular.element(document).ready( function(){
$('#mainNav ul, #mainNav li').removeClass('active');
$('#mitgliederNav').addClass('active');
fetchData();
} );
}
})();
Why is it not working inside this controller but in all other controllers, the $http.get ist working with authorization header?
EDIT
I tracked this behavior a little bit and found that something is removing the "Authorization" Header which has been set by the satellizer interceptor (for this controller request the method is fired and this header is really added by satellizer interceptor but it is getting removed afterwards and I dont't know where because I do not touch any header data or have own interceptors)... Is it a bug?
Try this one:
(function() {
'use strict';
angular
.module('authApp')
.controller('NewMitgliederController', NewMitgliederController);
function NewMitgliederController($http, $scope) {
var vm = this;
vm.error = {};
vm.fetchedData = {};
fetchData();
function fetchData() {
$http.get('APIv1/Beitragsgruppen/list/').then( function(res) {
vm.fetchedData.mitgliedsgruppen = res;
$('#mainNav ul, #mainNav li').removeClass('active');
$('#mitgliederNav').addClass('active');
}, function(err) {
vm.error = err;
});
}
}
})();
First, thanks for your help in advance. I'm a noob to angular though I did search quite a bit trying to resolve this issue. I'm guessing I missed something obvious. I'm using ui-router and using the resolve property to call a resource and can't get it for the life of me to pass the params to the web service.
First, my routes and states:
(function () {
"use strict";
var app = angular.module("MyModule",
["ui.router",
"ngResource",
"common.services"]);
app.config(["$stateProvider", '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider.state("home", {
url: "/",
templateUrl: "welcomeView.html"
})
$stateProvider.state("vehicleList", {
url: "/vehicles",
templateUrl: "App/Vehicles/vehicleListView.html",
controller: "VehicleListController as vm"
})
$stateProvider.state("vehicleEdit", {
url: "/vehicles/edit/:vin",
templateUrl: "App/Vehicles/vehicleEditView.html",
controller: "VehicleEditController as vm",
resolve: {
vehicleResource: "vehicleResource",
vehicle: function (vehicleResource, $stateParams) {
var vehicleVIN = $stateParams.vin;
return vehicleResource.get(
{ vin: $stateParams.vin }).$promise;
}
}
})
$stateProvider.state("vehicleDetails", {
url: "/vehicles/:vin",
templateUrl: "App/Vehicles/vehicleDetailsView.html",
controller: "VehicleDetailsController as vm",
resolve: {
vehicleResource: "vehicleResource",
vehicle: function (vehicleResource, $stateParams) {
var vehicleVIN = $stateParams.vin;
return vehicleResource.get(
{ vin: 'T123432342' }).$promise;
}
}
})
}
]);
}());
Note that you see a couple of varieties of passing the vin is as I've tried numerous ways with passing in the variable vehicleVIN, a string, etc. The vehicleVIN variable does assign properly there so injecting $stateParams or passing the vin to it doesn't seem to be the problem.
Here is the resource:
(function () {
"use strict";
angular
.module("common.services")
.factory("vehicleResource",
["$resource",
"appSettings",
vehicleResource]);
function vehicleResource($resource, appSettings) {
return $resource(appSettings.serverPath + "/api/Vehicle/:vin", { vin: '#vin' },
{
'update': { method: 'PUT' },
'details': { method: 'GET' },
'query': { method: 'GET', isArray = true }
});
}
}());
Here is common.services:
(function () {
"use strict";
angular
.module("common.services", ["ngResource"])
.constant("appSettings",
{
serverPath: "http://localhost:8098"
});
}());
And here is the service end of it (Asp.Net WebAPI):
// GET api/Vehicle
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All, AllowedOrderByProperties = "Name")]
[ResponseType(typeof(IQueryable<IEnumerable<IVehicle>>))]
public IHttpActionResult Get()
{
return ListOfVehicles...blah..blah
}
// GET api/Vehicle/5
[ResponseType(typeof(IQueryable<IVehicle>))]
public IHttpActionResult Get(string vin)
{
return SingleVehicle...blah...blah
}
Every time I execute it, the breakpoint hits Get (without the vin parameter) and when I run fiddler, it looks like it's sending an empty body.
Any ideas on what is going on? Much appreciated!
Is it possible to load a template from a other application (like a express app) via $http?
Or from an other external source?
Not with ui-router alone, though the following lazy loading module for ui-router exists which may help you achieve your goal: ocLazyLoad - https://github.com/ocombe/ocLazyLoad
An example of how it works (taken from http://plnkr.co/edit/6CLDsz)
define([
'angular',
'uiRouter',
'ocLazyLoad',
'ocLazyLoad-uiRouterDecorator'
], function (angular) {
var app = angular.module('app', ['ui.router', 'oc.lazyLoad', 'oc.lazyLoad.uiRouterDecorator']);
app.config(function($stateProvider, $locationProvider, $ocLazyLoadProvider) {
$ocLazyLoadProvider.config({
loadedModules: ['app'],
asyncLoader: require
});
$stateProvider
.state('home', {
url: "/",
template: "<p>Hello {{name}}. Would you like to... <a href='#lazy'>load lazy</a>?</p>",
controller: 'mainCtrl'
})
.state('lazy', {
url: "/lazy",
lazyModule: 'app.lazy',
lazyFiles: 'lazy',
lazyTemplateUrl: 'lazy.html',
controller: 'lazyCtrl'
});
$locationProvider.html5Mode(true);
});
app.controller('mainCtrl', function($scope) {
$scope.name = 'World';
});
});
It is possible but you'll have to use a templateProvider. More clear explanation using an example:
$stateProvider.state('state', {
url: '/state',
//templateUrl: 'templates/stateTemplate.html',
templateProvider: function ($http, $templateCache) {
var tplUrl = 'http://another.accesible.domain/stateTemplate.html',
tpl = $templateCache.get(tplUrl);
return (!!tpl) ? tpl :
$http
.get(tplUrl)
.then(function (response) {
tpl = response.data
$templateCache.put(tplUrl, tpl);
return tpl;
});
},
controller: 'stateController as sCtrl',
params: {
target: null
},
resolve: {
loadCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load(['stateController', 'appDataProvider', 'appDataService', 'stateFactory', 'stateService']);
}],
resolveObject: function ($window) {
var result = $window.localStorage.getItem('resolveObj');
return result;
}
}
})
Hope it helps (late answer I know, but just found this question looking for something else). ocLazyLoad is needed if you don't want to load everything at once when your app starts, but load what is required when it's required. Quite useful if your app's memory footprint is an issue.
Best regards.