environment specific config with angularjs - 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'
});

Related

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)

How to inject angular app with api url

I am building an angular app that uses a node api. I need a way to bootstrap the angular code with the url of the node api. I would like the node server to have a config file that holds its own url, which may vary based on dev, test, production, etc (e.g. http://localhost:4000/api or http://www.myproductionbox.com/api/v2).
What is the best way to get this the url from the server config file and merge it into the angular source code dynamically?
I am using jade for html templates and I can get something to work using those:
constants.jade:
|angular.module('myApp', []).value('baseUrl', '#{apiBaseUrl}')
where apiBaseUrl is defined in a config file. The express app renders the jade file like this:
app.get('/constants', function(req, res) {
res.render('constants.jade', { apiBaseUrl: settings.api.baseUrl })
})
This works but feels hacky. What's a better way?
We use an inline <script> to hold all those type of config parameters. Such as
<script>
window.config = {
baseUrl: '#{apiBaseUrl}'
};
</script>
This way your angular app can still live in an external file served from a cdn or something.
And then in your app you do what you were doing before with a slight modification.
angular.module('myApp', []).value('baseUrl', window.config.baseUrl)
You could also create a ConfigService in your app that exposes window.config. Then its easier to mock out those values in your tests.

AngularJS: Development and switching backends using Gulp

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.

Is it possible to build a hybrid app with Angular?

I build an AngularJS application that I expected to work as a hybrid application for mobile devices. As such the application would run locally from the file system.
When the $routeProvider gets the html file I get the following message.
This is a CORS violation obviously but the file is local and trying to access another local file. It's not like a web site is trying to access a clients local files. This is the client.
I can't spin up a web server to serve up the local files because this will be packaged up and deployed as a local application.
I know people build hybrid mobile applications all the time. What I can't figure out is how they do this with AngularJS and why AngularJS doesn't either offer a solution or prescribe how to get around CORS.
I'm open to all suggestions. Thanks all.
XMLHttpRequest cannot load file:///D:/SubversionRits/SourceCode/Verso%20-%20Mashup%20Proposal/MarshupSource/MashupCoreUI/core/apps/mashup/welcome/welcome.html. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource. VM36 angular.js:8380
Error: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'file:///D:/SubversionRits/SourceCode/Verso%20-%20Mashup%20Proposal/MarshupSource/MashupCoreUI/core/apps/mashup/welcome/welcome.html'.
Here is my route config
mashupApp.config(function ($routeProvider, $httpProvider) {
// I've tried all these with no effect.
//$httpProvider.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
//$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
//$routeProvider.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
//$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
//$httpProvider.defaults.useXDomain = true;
//delete $httpProvider.defaults.headers.common['X-Requested-With'];
$routeProvider
.when('/about', {
templateUrl: 'apps/mashup/about/about.html',
controller: 'aboutController',
resolve: {
loadMyCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
// you can lazy load files for an existing module
return $ocLazyLoad.load({
name: 'mashupApp',
files: ['apps/mashup/about/aboutController.js', 'apps/mashup/~appServices/dataService.js']
});
}]
, sessionLoad: function ($route, sessionLoad) { return sessionLoad.loadCompleted(); }
}
})
.when('/', {
templateUrl: 'apps/mashup/welcome/welcome.html',
sessionLoad: function ($route, sessionLoad) { return sessionLoad.loadCompleted(); }
}
})
;
});
I don't know the details, but I'm pretty sure HabitRPG's Android app uses Angular.
https://github.com/HabitRPG/habitrpg-mobile
Ok, I figured it out.
Running a web app from a file doesn't work because of CORS but when you are packaged up in Phonegap or Cordova inside the Intel XDK everything works.
I took my application and created a blank Intel XDK project and copied my web files to it without changing anything.
It all worked!
Thanks for those who offered ideas and suggestions. I really appreciate it.
I see how this can work now.
If you want to create a hybrid mobile app with AngularJS, you should definitely checkout the Ionic Framework.
From the Ionic website:
A match made in heaven. Ionic utilizes AngularJS in order to create a framework most suited to develop rich and robust applications. Ionic not only looks nice, but its core architecture is for serious app development, and AngularJS ties in perfectly.
You can't access the files directly due to browser security settings, but you can store data etc in localstorage and use that when the app is offline.
Someone has put together an example here http://amitavroy.com/justread/content/articles/html5-local-storage-angular-js

How to use Web Workers into a Module build with Requirejs?

I have a well working app writing with Requirejs and Backbonejs, but it's really slowing sometimes... For example when it comes to make some arithmetic work! I tried to use a Web Worker to do this arithmetic work like this :
My Module(traffic.js) :
define(["jquery", "use!underscore", "use!backbone", "namespace" ],
function ($, _, Backbone, globals) {
.....
var worker = new Worker("arithmetic.js");
worker.addEventListener('message', function(e) {
console.log(e.data);
}, false);
worker.postMessage(globals.data); // Send data to our worker.
});
arithmetic.js :
define(["use!underscore", "use!backbone" ],
function ($, _) {
//Here die Operations
});
But i have the Error define is not defined!!
I tried it like this too but no success!!
How to use Web Worker into requirejs or with backbonejs??
Thanks!
You can use requireJS from web workers: see the API docs for more info.
The only requirement is to load requireJS at the start of the web worker with importScripts(…). Once that is loaded, you can use define and use requireJS like normal.
The key part for me when I was getting it to work was to make sure that you are also loading the same bootstrap configuration (e.g. config.js or main.js) in the web worker that you are using in the rest of your app. This is what the doc is talking about when it says:
You will likely need to set the baseUrl configuration option to make sure require() can find the scripts to load.
Another thing is that you can load the worker from your traffic.js file with a module ID (instead of hardcoding the script path) utilizing this requireJS plugin.

Resources