How to test an http request in my case? - javascript

I have a service like this.
It is simply just make a http get request.
angular.module('myApp').service('TESTService', ['$http',
function($http) {
var request = function(url) {
return $http({
method: 'GET',
url: url
});
};
return {
get: function(url) {
return request(url);
}
};
}
]);
Within my controller, I have called the service
TESTService.get('/api/product' + id).success(
function(result) {
console.log(result)
}
);
I need to write the unit test for it
describe('test here', function () {
var testCtrl, scope, httpBackend, testService;
// Initialize the controller and a mock scope
beforeEach(inject(function (_$controller_, _$rootScope_, _$httpBackend_, _TESTService_) {
scope = _$rootScope_.$new();
httpBackend = _$httpBackend_;
testService = _TESTService_;
testCtrl = _$controller_('testCtrl', {
$scope: scope
});
it('should return http data', function() {
var productData = {
data: [
{
obj: {
id:'123'
}
}
]
}
httpBackend.expectGET('/api/product/' + id).respond(productData);
TESTService.get('/api/product/' + id).
then(function(data) {
var result = data;
})
httpBackend.flush();
expect(result).toEqual(productData)
});
}));
After running the test, I got
Error: Unexpected request: GET /api/product/undefined
How do I write the test to make sure it passes? Any ideas? Thanks a lot!

Your variable "id" seems to be undefined. If you throw in
var id = 123;
before this line:
httpBackend.expectGET('/api/product/' + id).respond(productData);
It would call /api/product/123 instead.
So maybe you were looking for this in the first place:
httpBackend.expectGET('/api/product/' + productData.data[0].obj.id).respond(productData);
TESTService.get('/api/product/' + productData.data[0].obj.id).
And so on... Hope it helps!

Try putting single quotes around the object that's passed into $http, i.e. $http({method: 'GET', 'url', url});
angular.module('myApp').service('TESTService', ['$http',
function($http) {
var request = function(url) {
return $http({
method: 'GET',
'url': url
});
};
return {
get: function(url) {
return request(url);
}
};
}
]);

Related

Angular JS Service Creation Error

I have created this service.
and using **enrollments.getProperty();**this statement to call this service but it's not working I'm new to angular-JS please let me know where I making the mistake.
var helloAjaxApp = angular.module("myApp", []);
helloAjaxApp.service('enrollments', [ '$scope', '$http', function ($scope, $http) {
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8";
var enrollments = null;
enrollment();
$scope.enrollment=function () {
$http({
url : 'enrollments',
method : "GET"
}).then(function(response) {
enrollments = response.data;
alert("enrollments");
});
};
return {
getProperty: function () {
return enrollments;
},
setProperty: function(value) {
enrollments = value;
}
};
}]);
use angular.module()
(function () {
'use strict';
angular.module("helloAjaxApp")
.service('enrollments', ['$scope', '$http', function ($scope, $http) {
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8";
var enrollments = null;
enrollment();
$scope.enrollment = function () {
$http({
url: 'enrollments',
method: "GET"
}).then(function (response) {
enrollments = response.data;
alert("enrollments");
});
};
return {
getProperty: function () {
return enrollments;
},
setProperty: function (value) {
enrollments = value;
}
};
}]);
});
Angular has 2 ways of defining a service: service and factory.
here you can see the difference: https://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html
The basic difference is that service is like a constructor, so you don't return an object from it but define the properties using this keyword:
this.getProperty = function () {
return enrollments;
}
When using the factory method, is expects an object to be returned with the exposed properties/functions.
You are using the factory syntax, so just change the definition to use factory:
helloAjaxApp.factory('enrollments', [ '$scope', '$http', function ($scope, $http)
You should go for a proper service structure like so:
var helloAjaxApp = angular.module("myApp", []);
function EnrollmentService($scope, $http) {
let _this = this;
this.enrollments = null;
this.getEnrollments = function() {
return $http({
url: 'enrollments',
method: 'GET'
}).then(function(response) {
_this.enrollments = response.data;
return _this.enrollments;
})
};
this.setEnrollments = function(enrollments) {
_this.enrollments = enrollments;
}
}
helloAjaxApp.service('enrollments', ['$scope', '$http', EnrollmentService]);
Then, use the service anywhere else:
enrollmentService
.getEnrollments()
.then(function(enrollments) {
// You can use the data here.
console.log(enrollments);
});
The controller code
LoginService is service name you have to pass as a parameter to controller
var loginModule = angular.module('LoginModule',[]);
loginModule.controller('logincontroller', ['$rootScope','$scope','$http','$window','$cookieStore',
'LoginService',logincontrollerFun ]);
function logincontrollerFun($rootScope, $scope, $http, $window,$cookieStore, LoginService,RememberService) {
$scope.loginTest = function() {
LoginService.UserStatus($scope, function(resp) {
console.log("response of login controller ::: ", resp);
///write ur code
});
}
}
service code
var loginModule = angular.module('LoginModule')
loginModule.factory("LoginService",[ '$http', LoginServiceFun ])
function LoginServiceFun($http) {
function UserStatus($scope,callback){
var targetRequestPath='./url';
var targetRequestParamsREQ={'email':$scope.email,'password':$scope.passWord};
return $http({
method: 'POST',
url: targetRequestPath,
headers: {'Content-Type': 'application/json'},
data: targetRequestParamsREQ
}).then(function (response){
console.log('Response Data : ', response.data);
callback( response.data );
})
}
return {
UserStatus:UserStatus
}
}

How do I convert a controller http call to a Service/factory pattern that takes in a parameter

I have a controller that is calling http.get, http.push and http.post methods.
I am learning angularjs and have found that it's best to call your http.get in your service file. I am able to do that with a simple http.get, but get confused with a http.get by id or http.get/http.post which takes a parameter:
My current controller looks like this
angular.module("app-complaints")
.controller("clcontrol", clcontrol);
function clcontrol($routeParams, $http, $scope) {
$http.get(baseURL + "/api/complaints/" + $scope.complaintCase + "/checklists")
.then(function (cl) {
//success
$scope.index = 0;
$scope.cl = [];
$scope.cl = cl;
}
I want to separate it out like this
controller.js
angular.module("app-complaints")
.controller('clcontrol', function ($http, $scope, $q, Service, $timeout) {
....
getCL();
function getCL(){
Service.getCl()
.success(function(cl){
$scope.cl = [];
$scope.cl = cl;
}
service.js
angular.module("app-complaints")
.factory('Service', ['$http', function ($http) {
Service.getCL = function () {
return $http.get(urlBase + "/api/complaints/" + complaintCase + "/checklists")
};
};
Simple. Make a factory that accepts parameters.
var app = angular.module("MyApp", [ /* dependencies */]);
app.factory("SharedServices", ["$http", function($http) {
return {
getItems: function(url, parameters) {
return $http.get(url, {
//optional query string like {userId: user.id} -> ?userId=value
params: parameters
});
},
postItem: function(url, item) {
var payload = {
item: item
};
return $http.post(url, payload);
},
deleteItem: function(url, item) {
var payload = {
item: item
};
return $http({
url: url,
data: payload,
method: 'DELETE',
});
}
// ETC. ETC. ETC.
// follow this pattern for methods like PUT, POST, anything you need
};
}]);
Use the service in your controller:
app.controller("MainCtrl", ["$scope","SharedServices", function($scope, SharedServices) {
//do things with the shared service
$scope.postMyThings = function() {
SharedServices.postItems('path/to/api', itemsArray).then(function(response) {
//success callback, do something with response.data
}, function(response) {
//an error has occurred
});
};
$scope.getMyThing = function() {
SharedServices.getItems('path/to/api/get').then(function(response) {
//success callback, do something with response.data
}, function(response) {
//an error has occurred
});
}
}]);

AngularJS: Get $http response from function in module

how do i get the response from $http in from a function in a module?
Angular module:
// module customServices
var customServices = angular.module("customServices", []);
// object for response
httpResponse = {content:null};
// function sendRequest
function sendRequest(param)
{
// inject $http
var initInjector = angular.injector(['ng']);
var $http = initInjector.get('$http');
// set header
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
$http({
// config
method: 'POST',
url: 'response.php',
data: $.param(param),
// success
}).success(function (response, status, headers, config) {
httpResponse.content = response;
// error
}).error(function (response, status, headers, config) {
console.warn("error");
});
}
// factory - moduleService
customServices.factory("moduleService", function () {
return {
// function - members
members: function(param)
{
switch(param.fc)
{
// getAll
case 'getAll':
sendRequest({
service :'members',
fc : param.fc,
id : param.id
});
return httpResponse;
}
},
};
});
Controller:
myApp.controller('main', ['$scope', '$http', 'moduleService', function($scope, $http, moduleService){
$scope.handleClick = function () {
var ReturnValue = moduleService.members({
fc:'getAll',
id:'123',
});
console.log(ReturnValue);
};
}]);
the object is on the first click empty and on the second click its content is the $http response.
but i want that the controller knows when the $http response is available.
i tried to use $broadcast and $on, but it seems to be impossible to use $rootScope in my function "sendRequest".
A couple of things:
Why are you defining the httpResponse instead of just returning something from the sendRequest function?
Why are you defining a function outside angular instead of putting it as a service or factory?
You should create a service with the sendRequest method inside like this:
customServices.factory("yourNameHere", function($http, $q) {
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
return {
sendRequest: function sendRequest(param) {
return $http({
method: 'POST',
url: 'response.php',
data: $.param(param),
})
.then(function(response) {
return response;
})
.catch(function(response) {
console.warn("error");
return $q.reject(response);
});
}
};
});
Then in the other service:
customServices.factory("moduleService", function (yourNameHere) {
return {
// function - members
members: function(param)
{
switch(param.fc)
{
// getAll
case 'getAll':
return yourNameHere.sendRequest({
service :'members',
fc : param.fc,
id : param.id
});
}
},
};
});
Now the result will be a promise, so you can consume the data like this:
moduleService.members({
fc:'getAll',
id:'123',
})
.then(function(result) {
console.log(result);
});

Can I pass values from $http.get to another functions in AngularJS

I'm trying to learn AngularJS, and I'm wondering if I can do this or not?:
Here is my code:
(function() {
function InfoController($scope,$element){
$scope.items = data['data']; //data in Option controller
}
function OptionController($scope,$element,$http){
$element.find(".list-group-item").click(function() {
var a = $(this).text();
$http({
url: 'hand',
method: "GET",
params: {a: a},
}).success(function(data){
console.log(data['data'][0]);
});
});
}
angular.module('testModule', [])
.controller('InfoController', InfoController)
.controller('OptionController', OptionController);
})();
I'm new in AngularJS and I don't know how to pass values data['data'] from $http.get in OptionController to InfoController, so please tell me how can I do that :)
Yes, you would do so with a service docs
app.service('dataService', function(http) {
this.data;
var self = this;
this.getData = function() {
return $http.get('/data').then(function(resp) {
self.data = resp.data;
return self.data
})
}
you would then pass in dataService to both controllers
$scope.data = dataService.getData()

Set up Relative Path for a all $https Call in AngularJS

I am new angularJS.
I have make call more then 10 $http request using services in my project.
One service code is given below.
loginApp.factory('serviceAuth', function($http) {
return {
fnLoginAuth : function(aut,resp){
return $http({
method: 'GET',
url: 'http://localhost:8080/myProjectname/serviceName',
}).success(function(result) {
return result;
});
}
}
});
I want http://localhost:8080/myProjectname/ this part of url is configurable or use a variable instead of this URL.
In my applications written in AngularJS, I just put the variable in the $rootScope.
app.run(['$rootScope',
function($rootScope) {
$rootScope.serverRoot = '/projectname/public';
}
]);
And append it to the services.
this.addTask = function(data) {
return $http.post($rootScope.serverRoot + '/task/create', data);
}
Why don't you add another service that returns the base URL?
app.factory('urlService', function() {
var url = "";
return {
setUrl : function(newUrl){
url = newUrl;
},
getUrl : function(){
return url;
}
}
});
and use it like this:
app.run(function(urlService) {
urlService.setUrl('http://localhost:8080/myProjectname/');
})
loginApp.factory('serviceAuth', function($http, urlService) {
return {
fnLoginAuth : function(aut,resp){
return $http({
method: 'GET',
url: urlService.getUrl() + 'serviceName',
}).success(function(result) {
return result;
});
}
}
});

Categories