Are modules in nancyfx really created on each request? - nancy

I have created a simple self hosted Nancy site with a single module in a console project. When testing it out I noticed that the module constructor is called on each request. This puzzles me because the ctor is also where routes are registered. That does not make sense to me and I must be missing something. So are module constructors called on each request and are all routes thus re-registered on each request?

Sort of - Nancy will construct all modules at startup, register all their routes and build the routing Tree. For each request it will then figure out which Module it needs and construct it using the request container, so request scoped dependencies have the correct lifetime, then executes the relevant action. The routes are not "registered" every request, they are just stored in a collection in the module and the engine executes the correct one.

Related

Blocking / Initialization service with angular.js

My apps are using many web services on the intranet, and url-s for those depend on the server environment.
My apps are hosted on IIS, which adds an HTTP response header like this: Environment: DEV, so every web app knows in which server environment it is running, and thus which intranet servers it must use to call all the services.
Each of my angular apps uses a service that issues a simple GET against the app's own root just to get any response with the environment name in it, and set configuration accordingly.
Question:
How should an angular app implement such a service that would execute as the very first thing in the application, and make sure that while it is getting that first response, nothing in the app tries to execute an HTTP request against other services, or even try to use any configuration provided by my environment service?
Is there a way to implement such a service in angular that could block every other service / factory in the application till it is done initializing itself?
I have many other services in the app, and none of them really know what to do till my environment service has finished its initialization.
UPDATE
Looking at it from another angle.... is it possible to implement such an interceptor in angular that could do the following?:
execute an HTTP request and block the app's execution till it gets a response
make information from the response available throughout the app as a service/factory/config.
Angular lifecycle could be one solution. Using the angular.config() phase you could peek at the headers of the HTTP service.
Create a factory called 'httpInterceptor'
function httpInterceptors(siteConfig, $q, $injector) {
return {
response: function(data, status, headers) {
siteConfig.setEnvironment(headers['Environment']);
return data;
}
};
)
Then in angular.config()
$httpProvider.interceptors.push('httpInterceptor');
If you truly want to block the other option is to use UI router resolve property to block routes loading until the request has been made https://github.com/angular-ui/ui-router/wiki you can add the resolve method to the root state.
Resolve
You can use resolve to provide your controller with content or data that > is custom to the state. resolve is an optional map of dependencies which > should be injected into the controller.
If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.

Pass environment variable through to Angular app

I'd like to configure my gulp webserver task to pass an environment variable into the angular app. Each team member has his own VM running the API and the variable would instruct the Angular app of the base API url. I'm trying to eliminate the need for every team member to remember to edit the config file after every TFS update.
I thought of simply setting a response header via middleware, but javascript cannot see response headers for the current page - only those of XHR responses.
So I try initializing the config service by performing a HEAD request against the web root, but this requires resolving a $http promise which requires adding a resolve to the route config to ensure it gets resolved before something tries to use it.
I tried just injecting a cookie via middleware and reading it with the $cookies service, but Internet Explorer apparently doesn't see 'localhost' as a valid domain name for cookies and does not read them.
So what other ways are there to allow an environment variable (or other form of local config) to be passed into the angular app?
We have solved this problem in many ways for different situations.
We don't use the base URL but just relative "/folder/resource".
We have an HttpHandler that resolves files with custom extension i.e. ".xyz". Then we have a file named "config.xyz" which is just a JavaScript file with something like:
{
baseUrl: [BASE_URL]
}
When the handler is asked to provide this file, the handler reads the file and does the replacements and then serve its content.
Use the one fake name for the server that serves the API. I.e: thisismylocalfake and then ask developers to configure their hosts file in system32
Have a gulp tasks that, when you compile the application, takes one config.js file and uses the machine name to replace a tag like in option 2.
I ended up adding middleware to the gulp-webserver to intercept a request for our config service file. Then I used gulp-replace and gulp-respond to inject the url from the environment variable directly in the stream. No files edited, technically and it works without having to have any sort of dev-specific code in the project.

Karma Jasmine AngularJS testing with real HTTP requests

I want to test my code with real API calls (so I can test the API as well, and when I change the API I don't have to change the JS test as well, and a lot more benefits.) instead of the regular $httpBackend.expectPOST('http://api.com/login').response(200).
Essentially, I want to test a ProductsController that expects to be logged in through an AuthService.login() method and receive a list of products through ui-router's resolve feature.
In this case, the login method receives data that needs to be used to gather products.
From the $httpBackend documentation found here: https://docs.angularjs.org/api/ngMockE2E/service/$httpBackend
As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application is being developed with the real backend api replaced with a mock, it is often desirable for certain category of requests to bypass the mock and issue a real http request (e.g. to fetch templates or static files from the webserver). To configure the backend with this behavior use the passThrough request handler of when instead of respond
So, something like: $httpBackend.whenGET(/.*/).passThrough(); should suffice.

Appending Param to AngularJS REST Queries

I'm using AngularJS with UI-Router and am attempting to attach a query parameter to a url on all http requests across my site.
I have an OAuth system on the backend and was previously applying Authorization headers to all requests, however to preserve backwards compatibility - have discovered I will have to instead apply a url parameter with the user identification to the backend.
My issue is that, I cannot use $httpInterceptor in the config portion of the app, because at that point in the app I don't have the current User, and can't inject $http to resolve the current user because that creates a circular dependency.
I was trying to use $http.defaults.transformRequest in the run portion of the app, but that didn't seem to be able to append a parameter to the url.
Is there a way to do this short of hand writing it on every REST request across the app?
I had similar problem in my current project.
To solve the problem I manually request current user info before app bootstapping & store it in localStorage.
Then bootstrap the app & in the config section you will have accesss to current user info.
TIP: to get user info before app bootstrap you can still use $http service by manually injecting it:
angular.injector(['ng']).get('$http');

Use Angular routing in an Apache-hosted app

My app's frontend is done in Angular while the backend is in PHP. For this last reason, I am using Apache as app server.
I want to use Angular's routing feature, that is, $routeProvider.when(), with conditional params (aka named groups) such as /user/:id/, where :id would be a parameter passed to the controller specified in the route.
Obviously, Apache tries to handle the request e.g., /user/21 by looking for a resource called 21 inside of the user directory, and thus returns a 404 error, instead of letting Angular routing load the resource at /user and using the value 21 to do internal stuff (such as calling an API).
How would I have to setup Apache so that some requests are left to be handled by Angular?

Resources