AngularJS: Development and switching backends using Gulp - angularjs

I need to switch my application server backend during development. Currently, the server is hard-coded in a module as a string.
I was looking around for a good way to switch the server using gulp.
I am unsure how to achieve something like gulp watch localhost or gulp watch devserver, where the last argument denotes the backend server?

You might have a configuration file for every different config, for example dev.constant.js and local.constant.js.
Each of these files contains an angular constant wich holds your current config, including your backend's url:
angular
.module('myFancyModule')
.constant('config', {
backendUrl: 'https://my.backend.com/api/'
});
Using yargs and gulp-if, you can check if a flag (e.g. --dev) is set and add the corresponding config file to the stream using gulp-add-src.
Another, more safe way is, to copy the particular config file to a file called config.constant.js once.
var argv = require('yargs').argv;
var fs = require('fs-extra');
gulp.task('watch', function() {
if(argv.dev) {
fs.copySync('./config/dev.constant.js', './config.constant.js');
}
//Your watch task here
}
Doing it this way, you are able to change your configuration very quick and easy. You could use this for builds and deploys as well, if you're doing them via gulp.

Related

How to clear browser cache when launching updated version of application?

I am deploying my UI application which is made up of AngularJS, Grunt and other UI things.
Whenever i update my UI and redeploy it using apache-tomcat, Browser is always getting my resources from cache. (As the path of new resources like css, html are same)
User needs to do CTRL+F5 (Hard reload) to clear cache and use new resources.
How can i force browser to clear cache when i redeploy application?
If somehow i can use angular + grunt to do this task than also it is
fine.
I don't want to update the versioning of my files each time i redeploy the product. As my files internally downloading many html files as well.
So somehow i want to clear the browser cache only.
Thanks!
You can't update cache without filenames versioning. But you don't have to do it manually. If you use Grunt, just check out some npm packages. Like this one for example: https://www.npmjs.com/package/grunt-cache-breaker
On rebuild it will create new hashes for your assets and inject them into your html files. So when your users will download your html files (they are downloaded, they are not cached), these html files will contain assets like css and js with new names, so the browser will force download instead of taking these files from memory.
You can add version to your html files
app.factory('preventTemplateCache', function () {
return {
'request': function (config) {
if (config.url.indexOf('partials') !== -1) {
config.url = config.url + '?t=' + 101;
}
return config;
}
}
})
and also give version to .js files as
<script src='app.js?v=101'></script>
101 is version number

Angular1 can not load local file

Using yeoman generator to write angular, when i add an menu.json in app directory. And try to use the service to get json file. It appears 404 errror.
angular.module('mealApp')
.service('foodFinder', function () {
// AngularJS will instantiate a singleton by calling "new" on this function
this.getMenu = function() {
return $.get('menu.json');
}
});
If you put your menu.json in app folder I can know its location is same as index.html.
How about $.get('index.html');
By Default yeoman generator when you use its command (Ex: grunt server) to start server it will auto host a server (Ex: http://localhost:9000) and auto load your index.html in app folder.
if you cannot it means you are using another way to start server and lost relative path.
Maybe you need to find your relative path to your menu.json (Ex: app/menu.json or something)

AngularJS better way to read config file?

I built a angularJS app that I wanted dynamically configured, so I created a config.json file with the needed configurations, and decided to load the config file in app.config as such:
angular.module("myapp",[]).config([ my injections] , function(my providers){
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("GET","config.json"); //my config file
xhr.send();
xhr.onreadystatechange=function()
{
if (xhr.readyState==4 && xhr.status==200)
{
//config file parsed, set up params
}
}
})
The reason I am doing it this way is because $http is not injected in config state, and I do not want to "configure" the app at a controller level.
The application works fine. it does what I want to do, and everything works great...EXCEPT when it comes to unit testing (with karma + jasmine).
even though in karma.conf i have:
{pattern: 'config.json',served:true,watched:false,included:false}
defined, when I launch karma, I get a cli [WARN] about config.json 404. and my unit tests to see if everything is configured, fails (i.e it didnt read config.json)
Is there a better way to write config files for unit testing?
In our apps we have external file config.js, which contains just ordinary module which provides constants with configuration.
angular.module('myAppPrefixconfig')
.constant('PLAIN_CONSTANT', 'value'),
.constant('APP_CONFIG', {...});
In your app you have dependancy on it, and there is ordinary http request - which can be resolved by your backend with proper configuration.
In Karma tests you can then provide 'testing config' directly in karma.conf.

environment specific config with angularjs

I am working on creating a website with Angularjs and WebAPI as backend support with Visual studio.
I have defined the url to webapi in app.config.js as an app constant:
var serviceBase = 'http://localhost/Webapiservice/';
app.constant('ngAppSettings', {
apiServiceBaseUri: serviceBase,
clientId: 'ngTestApp'
});
Now for QA environments (http://QAServer/Webapiservice/), the webapi resides at a different URL, the same goes for our production environment (http://ProdServer/Webapiservice/).
I can manually update the js file to the appropriate location. But is there a way to automate this process so webAPI is pointing to the correct URL?
Is it possible to do this with grunt? Again I have never used grunt before.
ngConstant does a great job, along with grunt: https://github.com/werk85/grunt-ng-constant. This way you can specify your environments as JSON files and on compile/run time, grunt generates a enviornment.js file with a module (I call mine always ENV), which can be injected in every part of your application.
I would do something like this:
angular
.module('app', [])
.value('$path', {
rest : "http://localhost/Webapiservice"
})
you will call something like this:
app.constant('ngAppSettings', {
apiServiceBaseUri: $path.rest,
clientId: 'ngTestApp'
});

$httpbackend from ngMockE2E never called

I'm trying to make some backendless e2e tests, so I need to mocks API calls.
Here is what I did:
angular.module('foo.bar.e2eConf', ['foo.bar', 'ngMockE2E']).
run(function($httpBackend) {
$httpBackend.whenGET('/foo/bar').respond({foo:'bar'});
});
Then I configured my conf/karma.e2e.conf like this (pathes are ok):
var basePath = '../';
var files = [
ANGULAR_SCENARIO,
ANGULAR_SCENARIO_ADAPTER,
// bower libs
'components/angular/index.js',
'components/jquery/jquery.js',
'components/angular-resource/index.js',
'components/angular-mocks/index.js',
'components/chai/chai.js',
'test/chai.conf.js',
'src/app/**/*.js',
{pattern:'src/app/**/partials/*.tpl.html', included:false},
'test/e2e/**/*.js'
];
var singleRun = false;
var browsers = ['Chrome'];
var proxies = {'/': 'http://localhost:8000/'};
I can run tests that doesn't involve API calls, but when I run a test that involves it I get a nice Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:9876/foo/bar
I guess I misconfigured some stuff, but I can't figure out what??
Is there a conflict between the proxy and the mock? i.e. proxying /foo/bar to http://localhost:8000/foo/bar instead of using the mock?
Any idea?
Regards
Xavier
You need to create a version of your app that bootstraps off the foo.bar.e2eConf module, instead of bootstrapping off the foo.bar module.
You'll have to include the javascript files angular-mocks.js and the new module you defined above in your app index page.
You should be able to test this outside Karma by just using this new app and seeing it return data from your mocks.
You probably don't need to add half those files to the Karma configuration. That's just for adding files to the testing scenario.. its going to load your app in an iframe and your app is responsible for loading it's own javascript.
I'm using php to server up either version of the app depending on what URL I use: either the real version that uses the api calls, or the e2e version that uses the mocks.

Resources