can i set a base url for expect() - javascript

My restangular call has a baseUrl set in a config file to http://localhost:3000/. So a call like
Restangular.all("awards").customPOST(award)
Calls at baseUrl+"awards"
Now when I write a test for this, i have to write:
httpBackend.expectPOST("http://localhost:3000/awards")
But later if this baseUrl changes, I will have to change it in a lot many .expect() methods.
Is there anyway to set a baseUrl for the expect method, in a config file somewhere?
So that the expect method something like-
httpBackend.expectPOST(baseUrl + "awards");
So that any change in the baseUrl does not require any change in the expect() method?

You can create an angular.constant and then inject that constant wherever it is required.
var app = angular.module('app', []);
app.constant('Configuration', {
BASE_URL: 'http://localhost:3000/'
});
app.factory('RestApiService', function($http, Configuration) {
var awardApi = Configuration.BASE_URL + '/awards';
return {
getAwards: fucntion() {
return $http.get(awardApi);
};
};
});

Related

Require is not defined in AngularJS

I have two modules namely 'users' and 'groups', and have different routes in both of them. Now I want to use them in some other module, I am trying to require both the modules but getting error as required is not defined. How can I resolve it?
Here is my code:
appGroup.js
let myNinjaAppforGroup = angular.module('myNinjaAppforGroup',['ngRoute']);
//injected ngRoute module as a dependency in the above statement
myNinjaAppforGroup.config(['$routeProvider',function($routeProvider)
{
//code executes before application runs
$routeProvider
.when('/group/home',{
templateUrl:'views/home.html', //which view to be rendered if user visits this url
})
.when('/group/directory',{
templateUrl:'views/directory.html',
controller:'NinjaController'//it will be the controller for the mentioned route
}).otherwise({
redirectTo:'/group/home'
});
}]);
myNinjaAppforGroup.run(function()
{
//code executes when application runs
});
myNinjaAppforGroup.controller('NinjaController',['$scope','$http',function($scope,$http){
//scope is the glue between controller and view. Its also a dependency
$scope.message="Hey Angular!";//this is accessable in views
$scope.removeNinja = function(ninja)
{
let removedNinja = $scope.ninjas.indexOf(ninja);
$scope.ninjas.splice(removedNinja,1);
}
$scope.addNinja = function()
{
$scope.ninjas.push({
name:$scope.newNinja.name,
rate:parseInt($scope.newNinja.rate),
belt:$scope.newNinja.belt,
available:true
});
$scope.newNinja.name="";
$scope.newNinja.rate="";
$scope.newNinja.belt="";
}
$http.get('model/ninjas.json').then(function(response){
$scope.ninjas=response.data;
//console.log(response); for checking the object received
//whatever data we are getting from the http service is being saved here.
})
}]);
module.exports = myNinjaAppforGroup;
`and appUsers.js`
let myNinjaAppforUsers = angular.module('myNinjaAppforUsers',['ngRoute']);
//injected ngRoute module as a dependency in the above statement
myNinjaAppforUsers.config(['$routeProvider',function($routeProvider)
{
//code executes before application runs
$routeProvider
.when('/user/home',{
templateUrl:'views/home.html', //which view to be rendered if user visits this url
})
.when('/user/directory',{
templateUrl:'views/directory.html',
controller:'NinjaController'//it will be the controller for the mentioned route
}).otherwise({
redirectTo:'/user/home'
});
}]);
myNinjaAppforUsers.run(function()
{
//code executes when application runs
});
myNinjaAppforUsers.controller('NinjaController',['$scope','$http',function($scope,$http){
//scope is the glue between controller and view. Its also a dependency
$scope.message="Hey Angular!";//this is accessable in views
$scope.removeNinja = function(ninja)
{
let removedNinja = $scope.ninjas.indexOf(ninja);
$scope.ninjas.splice(removedNinja,1);
}
$scope.addNinja = function()
{
$scope.ninjas.push({
name:$scope.newNinja.name,
rate:parseInt($scope.newNinja.rate),
belt:$scope.newNinja.belt,
available:true
});
$scope.newNinja.name="";
$scope.newNinja.rate="";
$scope.newNinja.belt="";
}
$http.get('model/ninjas.json').then(function(response){
$scope.ninjas=response.data;
//console.log(response); for checking the object received
//whatever data we are getting from the http service is being saved here.
})
}]);
module.exports = myNinjaAppforUsers;
Now I have another file as app.js, I want to require these two files there, how can this be done?
Require doesn't work in browser.Basically require is a node_module by which we can access other modules or files.So please if you are using it on browser side then try other things like import or self.import or injecting.
Doc: http://requirejs.org/docs/download.html
Add this to your project: http://requirejs.org/docs/release/2.2.0/minified/require.js
and take a look at this http://requirejs.org/docs/api.html

Angular 1.5 component/require dependency injection of $log

I have been trying to inject $log in to a component created by a require statement for some client Angular.
var App = require('./app/containers/App');
var Header = require('./app/components/Header');
require('angular-ui-router');
var routesConfig = require('./routes');
import './index.css';
angular
.module('app', ['ui.router'])
.config(routesConfig)
.controller(App.App, ['$log'])
.service('todoService', todos.TodoService)
.component('app', App)
.component('headerComponent', Header);
The code for header is
module.exports = {
template: require('./Header.html'),
controller: Header,
bindings: {
todos: '='
}
};
/** #ngInject */
function Header(todoService) {
this.todoService = todoService;
}
Header.prototype = {
handleSave: function (text) {
if (text.length !== 0) {
this.todos = this.todoService.addTodo(text, this.todos);
}
}
};
~
The code for App is
module.exports = {
template: require('./App.html'),
controller: App
};
function App($log) {
this.log = $log;
$log.error('Hello from App');
}
I can inject $log as dependency for App as I have access to the controller. But attempting the same task for Header is difficult,because Header is created by require which does not seem to allow access to the controller function.
What I like to know is there a way round this?
I am trying to find a way of logging information from any possible javascript function in header.js.
I have seen any alternatives other than using $log to log information in a client side application
My solution so far has been to say in code written in the require block.
var ing = angular.injector(['ng']);
this.$log = ing.get('$log');
this.$log.error('I am a message');
I think this is the wrong way of doing things, it gives me what I want, but I expect it will break at some point. I find having access to $log is useful for debugging only. Its not sort of thing I need for any production code.
All I was trying to do was to get access to the $log angular wrapper. Turns out all I had to do was add $log to the argument list.
function Header(todoService,$log) {
$log.log('I am a log message');
this.todoService = todoService;
}
I am bit of a Angular 1.5 newbie and I had assume that you had to inject the $log to get the right response. Just declare it seems to be a bit of a kop out.

Debug mock httpbackend requests

I have a situation where there are many mocked http requests. While working on angular upload, something fishy happening in my case. It is always throwing status:200 success and html complete body response.
Below is my angular upload code:
function fileUploadController(FileUploader) {
/* jshint validthis: true */
let vm = this;
vm.type = this.type;
vm.clientId = this.client;
let uploader = new FileUploader({
url: 'http://localhost:8001/prom-scenario-config/files?clientId=' + vm.clientId,
data: {type: vm.type}
});
vm.uploads = {uploader};
vm.upload = upload;
vm.uploads.uploader.queue = [];
vm.uploads.uploader.onCompleteItem = function (item, response) {
let type = item.uploader.data.type;
console.log('response => ', response);
};
}
mock of httpbackend code looks like this:
$httpBackend.whenPOST(new RegExp('http://localhost:8001/prom-scenario-config/files\\?clientId=([a-zA-Z0-9-])$$'))
.respond(function () {
return [200, 'foo'];
});
But there is no affect on this.
Is there any error in my regex code in constructing?
With or without having the mock code. Still the response i am receiving is 200.
There are so many mock requests, i am facing difficulty in identifying which request is being called.
Is there any tricky way to identify which regex call is called? Or enforce my request to mock?
Below is the reference for status and response FYI.
Unit test suppose that a unit is tested in isolation. Any other thing which is not a tested unit, i.e. a controller should be mocked, especially third-party units.
Considering that it is tested with Jasmine, FileUpload service should be stubbed:
beforeEach(() => {
// a spy should be created inside beforeEach to be fresh every time
module('app', { FileUpload: jasmine.createSpy() });
});
And then controller is tested line by line like:
it('...', inject(($controller, FileUpload) => {
const ctrl = $controller('fileUploadController');
...
expect(FileUpload).toHaveBeenCalledTimes(1);
expect(FileUpload).toHaveBeenCalledWith({ url: '...', type: {...} });
// called with new
const fileUpload = FileUpload.calls.first().object;
expect(fileUpload instanceof FileUpload).toBe(true);
expect(ctrl.fileUpload).toBe(fileUpload);
expect(fileUpload.onCompleteItem).toEqual(jasmine.any(Function));
expect(fileUpload.queue).toEqual([]);
...
}));
In the code above clientId=([a-zA-Z0-9-]) regexp part matches only ids consisting of a single character, which isn't true. That's why it is preferable to hard-code values in unit tests, human errors are easier to spot and detect. It's not possible to unambiguously identify the problem when the tests are too loose, this results in wasted time.

Loading a JSON into AngularJS Project Globally

The angular project I am working on is adding a configuration file to it. The configuration file is loaded as a JSON, it contains strings that will be replacing the static strings that are currently used in the current version of the project. There is multiple modules where the JSON's data needs to be used, what would be the best way to make the JSON file global throughout the project? I was thinking about loading it separately in each module using a HTTP GET, but I need the JSON to be loaded before everything else.
Thanks.
You probably can use a service. define a object on the scope and on that define the JSON. create a function which returns the JSON and inject it wherever the need arises. Implementation maybe like:
app.service("commonService", ["$log", function($log){
this.myConfiguration = {
id:"0",
name:"abc"
};
this.mystatic = function(){
return myConfiguration;
}
}
Now you can inject it and use in a controller as:
app.controller("mycontroller", function($scope, commonService){
$scope.static = commonService.myStatic();
//other code here
});
you can use value:
// create the module as usual
angular.module("myapp",[/*...*/]);
// on any other app point, set your json:
angular.module("myapp").value("myjson",{/*...*/});
If you don't need is before you do any routing you could use a service. This is what a config service could look like:
(untested)
app.service('ConfigService', function ($q, $http) {
// loads the config file
this.loadConfig: function() {
var deferred = $q.defer();
if(angular.isDefined(this.config) && this.config.length){
deferred.resolve(this.config);
}
$http.get('config.json')
.success(function(response) {
this.config = response;
deferred.resolve(this.config);
})
.error(function(){
deferred.reject('Could not load "config.json" file');
});
return deferred.promise;
};
// returns a config setting
this.get: function(key){
// if the config is not loaded yet, load it and call self
if(!angular.isDefined(this.config) || !this.config.length){
this.loadConfig().then(function(){
return this.get(key);
})
}
// config is loaded. Return requested key
if(angular.isDefined(config[key])){
return config[key];
}else{
console.error( 'Could not load config value: ' + key );
return false;
}
};
});

Accessing globals from node.js modules?

I want to separate some functions into a file named helpers.js, in which I have put the below shown code. What should I do to access the app variable from inside my method in order to be able to fetch my config element named Path?
Helpers = {
fs: require('fs'),
loadFileAsString: function(file) {
return this.fs.readFileSync( app.set('Path') + file)+ '';
}
}
module.exports = Helpers;
So from what I see you need the app variable form Express. You can send it as a function param to loadFileAsString, for ex:
helpers.js
Helpers = {
...
loadFileAsString: function(file, app) {
return this.fs.readFileSync( app.set('Path') + file)+ '';
}
}
module.exports = Helpers;
some_file.js
app = express.createServer();
...
helpers = require('./helpers.js');
helpers.loadfileAsString(file, app);
If you want the app to be global though you can do that also: global.app = app and you can access app everywhere without sending it as a function param.

Categories