$httpBackend .whenGet is not a function in Angular - angularjs

I am trying to make a dummy service to get data in Angular, I am using ngMockE2E, and my code for the Mock looks like this:
(function () {
"use strict"
var app = angular
.module("productResourceMock", ["ngMockE2E"]);
app.run(function ($httpBackend) {
var products = [
{
"productId": 1,
"productName": "mobile1",
"productCode": "heh4",
"releaseDate": "May 21, 2013",
"description": "very nice mobile",
"cost": 200,
"price": 300,
"category": "Electronics",
"tags": ["mobile", "electronic"],
"imageUrl": "images/img1.jpg"
},
{
"productId": 2,
"productName": "mobile2",
"productCode": "heh4",
"releaseDate": "May 21, 2012",
"description": "not a nice mobile",
"cost": 100,
"price": 500,
"category": "Electronics",
"tags": ["mobile", "Electronic"],
"imageUrl": "images/img2.jpg"
}];
var productUrl = "/api/products";
$httpBackend.whenGet(productUrl).respond(products);
});
}());
I have defined my controller, and inside it, it has this code:
(function () {
"use strict"
angular
.module("productManagement")
.controller("ProductListCtrl",
["productResource",
ProductListCtrl]);
function ProductListCtrl(productResource) {
var vm = this;
productResource.query(function(data){
vm.products = data;
});
}
}());
And for my service that sends the REST requests, I have this code:
(function () {
"use strict"
angular
.module("common.services")
.factory("productResource",
["$resource", productResource]);
function productResource($resource) {
return $resource("/api/products/:productId");
}
}());
am still getting this error: Uncaught TypeError: $httpBackend.whenGet is not a function.
Any help is appreciated, or any clarification needed, please let me know.

Answer is simple: replace whenGet with whenGET
Be careful to write the http verb all in uppercase.
See ngMock documentation

Related

Angular $http service not getting objects from .JSON file

Here is my http service code:
app.controller('StoreController', ['$http', function($http){
var store = this;
store.products = [];
$http.get('/store-products.json').then(function(data){
store.products = data;
});
}]);
And here is my JSON code:
[
{
"name": "...",
"price": 20.00,
"description": "...",
"canPurchase": false,
"images": [
"...jpg",
"...jpg",
"...jpg"
],
"reviews": []
},
{
"name": "...",
"price": 15.95,
"description": "...",
"canPurchase": true,
"images": [],
"reviews": []
}
]
When I run the code on localhost server, it does not show my objects. There is also no errors in the console that show so I cannot see where I am going wrong. Can anyone see the issue here?
your json data is wrapped at response.data of $http.get.
change to below code will solve the problem(also make sure your json file is at right location).
$http.get('/store-products.json').then(function(res){
store.products = res.data;
});
Plunker demo.

Error while running angularJS unit test case in Karma-Jasmine

MainCtrl.js
var app = angular.module('mailApp');
app.controller('MainCtrl', ['$scope','$http',function($scope,$http) {
$scope.sortType = 'date'; // set the default sort type
$scope.sortReverse = false; // set the default sort order
$scope.inboxDetails = [];
$scope.loadInboxData = function(a){
if(a==1){
$http.get('inboxData.json')
.then(function(response){
$scope.inboxData = response.data;
});}
else if(a==2){
$http.get('inboxData1.json')
.then(function(response){
$scope.inboxData = response.data;
});}
}
//-----------------------------------------------
testMainCtrl.js
'use strict';
describe('MainCtrl', function () {
var $controller;
beforeEach(module('mailApp'));
beforeEach(inject(function(_$controller_){
$controller = _$controller_;
}));
//Test cases to verify Inbox Data
describe('$scope.loadInboxData', function () {
it('Inbox data is called', function () {
var $scope = {};
var controller = $controller('MainCtrl', {$scope: $scope});
$scope.inboxData = [{"subject": "Angular Example 11", "date": "3/8/2016", "to": "test1", "from":"abcd1","details":"Test Message 1" },{ "subject": "Angular Example 21", "date": "3/8/2016", "to": "test2", "from":"abcd2","details":"Test Message 2" },{ "subject": "Angular Example 31", "date": "4/8/2016", "to": "test3", "from":"abcd3","details":"Test Message 3" },{ "subject": "Angular Example 41", "date": "5/8/2016", "to": "test3", "from":"abcd4","details":"Test Message 4" }];
var a=$scope.loadInboxData(1);
expect($scope.inboxData).toEqual(a);
});
});
});
//------------------------------------------------
Error :
Chrome 48.0.2564 (Windows 10 0.0.0) MainCtrl $scope.loadInboxData
Inbox data is called FAILED
Expected
[
Object( {
subject:'Angular Example 11',
date:'3/8/2016',
to:'test1',
from:'abcd1',
details:'Test Message 1'
} ),
Object( {
subject:'Angular Example 21',
date:'3/8/2016',
to:'test2',
from:'abcd2',
details:'Test Message 2'
} ),
Object( {
subject:'Angular Example 31',
date:'4/8/2016',
to:'test3',
from:'abcd3',
details:'Test Message 3'
} ),
Object( {
subject:'Angular Example 41',
date:'5/8/2016',
to:'test3',
from:'abcd4',
details:'Test Message 4'
} )
]
to equal undefined.
You have a hard dependency on $http in your test. You should mock a return value from the $http service.
Take a look at the documentation https://docs.angularjs.org/api/ngMock/service/$httpBackend.
This may help you, $httpBackend is mock of $http
'use strict';
describe('MainCtrl', function () {
var $controller,$httpBackend;
beforeEach(module('mailApp'));
beforeEach(inject(function(_$controller_){
$controller = _$controller_;
}));
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
}));
//Test cases to verify Inbox Data
describe('$scope.loadInboxData', function () {
it('Inbox data is called', function () {
var $scope = {};
var controller = $controller('MainCtrl', {$scope: $scope});
$scope.inboxData = [{"subject": "Angular Example 11", "date": "3/8/2016", "to": "test1", "from":"abcd1","details":"Test Message 1" },{ "subject": "Angular Example 21", "date": "3/8/2016", "to": "test2", "from":"abcd2","details":"Test Message 2" },{ "subject": "Angular Example 31", "date": "4/8/2016", "to": "test3", "from":"abcd3","details":"Test Message 3" },{ "subject": "Angular Example 41", "date": "5/8/2016", "to": "test3", "from":"abcd4","details":"Test Message 4" }];
$httpBackend.when('GET', 'inboxData.json').respond(yourjsonresponseData1);
$httpBackend.when('GET', 'inboxData2.json').respond(yourjsonresponseData2);
var a=$scope.loadInboxData(1);
expect($scope.inboxData).toEqual(a);
});
});
});

how do i access deeply nested json object in angularjs

Here, I am suppose to access the top level market details from the Json data on the first page which I'm able to although Im not able to access the sub level market details. Im suppose to display the sub level market names on the next page.
$scope.myData = {
"market": [{
"mid": 3,
"mname": "mark1",
"submarket": [{
"id": 20,
"name": "val1"
}, {
"id": 24,
"name": "val2",
"submarket": [{
"id": 26,
"name": "val21"
}]
}]
"market": [{
"mid": 4,
"name": "mark1.1",
"submarket": [{....
}]
}]
}, {
"mid": 6,
"mname": "mark2",
}]
};
$scope.markname = []; /*stores top level markets*/
angular.forEach($scope.myData.market, function(org) {
$scope.markname.push(org)
}) /*works fine and has the details of market (mid:3 and mid:6)*/
$scope.submark = [];
angular.forEach($scope.markname.submarket, function(sorg) {
$scope.submark.push(sorg)
}) /*doesn't store anything*/
It should be:
$scope.submark = [];
angular.forEach($scope.markname, function(sorg) {
angular.forEach(sorg.submarket, function(subsorg) {
$scope.submark.push(subsorg)
});
});
JSFiddle
$scope.markname is an array and your pushing items into it on your first forEach, however in the second your trying to access the property submarket. This doesn't exist on the markname array, it exists on each item within the array.
Ive done my example using the native forEach there's no need for angular to get involved here at all, it also hides the undefined issue, as the native is available of the array prototype it throws an exception if you try to call it of undefined, whilst angular happily accepts undefined and continues.
So a simple fix would be
markname.forEach(function(sorg) {
if (sorg.hasOwnProperty('submarket')) {
submark.push(sorg.submarket);
}
});
See fiddle: https://jsfiddle.net/0y6r0mw1/
edit: Its worth noting this will produce a multidimensional array, if this is not wanted you can concat them all together with something like:
submark.push.apply(submark, sorg.submarket);
The json data that you have shared, is improper. Please go through this demo.
HTML:
<div ng-app="app" ng-controller="test">
</div>
JS:
var app = angular.module('app', []);
app.controller('test', function ($scope) {
$scope.myData = {
"market": [{
"mid": 3,
"mname": "mark1",
"submarket": [{
"id": 20,
"name": "val1"
}, {
"id": 24,
"name": "val2",
"submarket": [{
"id": 26,
"name": "val21"
}]
}, {
"mid": 4,
"name": "mark1.1",
"submarket": [{
"id": 27,
"name": "val221"
}]
}]
}, {
"mid": 6,
"mname": "mark2",
}]
};
$scope.markname = []; /*stores top level markets*/
angular.forEach($scope.myData.market, function (org) {
$scope.markname.push(org)
}) /*works fine and has the details of market (mid:3 and mid:6)*/
console.log('markname', $scope.markname);
$scope.submark = [];
angular.forEach($scope.markname, function (sorg) {
angular.forEach(sorg.submarket, function (subM) {
$scope.submark.push(subM)
})
})
console.log('submark', $scope.submark);
});
function iterate(obj) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property]);
}
else {
console.log(property + " " + obj[property]);
}
}
}
}
iterate(object)

AngularJS deferred $http.get response, empty array

Please help in changing this code to be able to use $http.get html, at the moment the resulting array (html_controls) is empty. However, I can see the response in the console for all the request in $http.get. Thank you.
angular.module('exodus-grid').controller('DynamicPropertiesController', ['$scope', '$http', '$templateCache', '$q', 'coreFactory',
function($scope, $http, $templateCache, $q, coreFactory) {
//$scope.DynamicProperties = 'Property being added to the controller.';
//coreFactory.fetchData('http://uat.resources.newscdn.com.au/cs/networksales/products/latest/products.json', 'products');
// TODO: Change this harcoded value to the products.json in s3
$scope.products = [{
"id": "btyb",
"label": "BTYB + Superskin",
"description": "",
"name": "btyb",
"active": true,
"properties": [{
"bannerLink": [{
"tmp_prop_name": "bannerLink",
"label": "Header Tracking Link (Desktop)",
"type": "textbox"
}],
"superskinLink": [{
"tmp_prop_name": "superskinLink",
"label": "Sideskin Tracking Link (Desktop)",
"type": "textbox"
}],
"ImgUrl": [{
"tmp_prop_name": "ImgUrl",
"label": "Header Image Url",
"type": "textbox"
}]
}]
}, {
"id": "iframe",
"label": "iframe",
"description": "",
"name": "iframe",
"active": true,
"properties": [{
"link": [{
"tmp_prop_name": "link",
"label": "iFrame source Url",
"type": "textbox"
}]
}]
}];
var requests = [];
var html_controls = [];
var product = $scope.products[0];
var properties = angular.fromJson(product.properties);
//console.log(angular.toJson(properties));
angular.forEach(properties, function(property) {
angular.forEach(property, function(item) {
//console.log(angular.toJson(property));
if (item[0].type === "textbox") {
//console.log(angular.toJson(item));
//console.log(Object.getOwnPropertyNames(property));
//console.log(Object.keys(property));
$http.get("plugins/k-plugin-exodus-grid/templates/properties/textbox.html").success(function(html) {
html = html.replace("%%label%%", item[0].label);
html = html.replace("%%scope%%", item[0].tmp_prop_name);
//console.log(html);
html_controls.push(html);
console.log(html_controls);
var deferred = $q.defer();
requests.push(deferred.promise);
console.log(deferred, deferred)
}).then(function() {
//$scope.html = html_controls;
});
}
});
});
//console.log(html_controls);
//$scope.html = html_controls;
$q.all(requests).then(function(data) {
console.log("12312312 " , data);
$scope.html = html_controls;
});
}
]);
Looks like you are trying to resolve a array of empty promises. Since it is running async, when $q.all() us called, requests[] is still empty.
Try building an array of promises and then resolve this using q.all() instead:
var requests = []; // a list of promises
angular.forEach(properties, function(property) {
angular.forEach(property, function(item) {
var promise = $http.get("/yoururl"); // $http.get returns a promise
requests.push(promise); // add to list of requests as a promise
});
});
$q.all(requests).then(function (result) {
console.log('results' + result);
});

Angularjs first attempt at dependency injection

I have a UserAddController and I want to be able to access a list of countries returned by a Web API. The Web API returns data fine. Here is my app.js where I get the data :
app.factory('Country', function ($resource) {
return $resource(
"/api/country/:Id",
{ Id: "#Id" },
{ "update": { method: "PUT" } });
});
This is my Controller :
var UserAddController = function ($scope, $location, service, User) {
$scope.action = "Add";
$scope.countries = service.countries;
};
I am declaring and creating a service here :
app.factory('CountryService', CountryService);
function CountryService($resource) {
return $resource(
"/api/country/:Id",
{ Id: "#Id" },
{ "update": { method: "PUT" } });
}
I am using the same code as above just for testing purposes. I am injecting this service like this :
UserAddController.$inject = ['$scope', 'CountryService'];
This is my first attempt at dependency injection and I cannot figure out where I am going wrong. The error I currently get is 'service is undefined'. I have tried passing both the service and the Country object to the Controller with the same results. Can anybody give any advice?
EDIT : In my Controller, this populates successfully with an alert in the code, but without the alert does not populate. Any reason why this is?
function CountryService($rootScope, $http) {
var self = {};
//self.countries = [{ "$id": "1", "CountryId": 1, "CountryName": "United Kingdom" }, { "$id": "2", "CountryId": 2, "CountryName": "Republic of Ireland" }, { "$id": "3", "CountryId": 3, "CountryName": "Australia" }, { "$id": "4", "CountryId": 4, "CountryName": "New Zealand" }, { "$id": "5", "CountryId": 5, "CountryName": "United States" }, { "$id": "6", "CountryId": 6, "CountryName": "France" }, { "$id": "7", "CountryId": 7, "CountryName": "Germany" }, { "$id": "8", "CountryId": 8, "CountryName": "Finland" }];
$http({
method: 'GET',
url: '/api/country'
}).success(function (data, status, headers, config) {
self.countries = data;
});
alert(self.countries);
return self;
}
You need to add other services/dependencies.
UserAddController.$inject = ['$scope',
'$location',
'CountryService',
'UserService'];
I have assumed that last dependency is a service with name 'UserService'. It's signature would be
app.factory('UserService', UserService);
Edit :
You need to instantiate a new variable.
//Inside function body
$scope.countries = service.countries;
$scope.newCountry = $scope.countries.get({Id : someId},callbackFn);
Now you have a counrtry with 'someId' in $scope.newCountry
Make sure you injected ngResource.
app = angular.module("app", ['ngResource']);
You need to inject the modules correcly
UserAddController.$inject = ['$scope', '$location', 'CountryService', 'user'];
This is quoted the doc.
You can specify the service name by using the $inject property, which
is an array containing strings with names of services to be injected.
The name must match the corresponding service ID registered with
angular. The order of the service IDs matters: the order of the
services in the array will be used when calling the factory function
with injected parameters.
I created a FIDDLE and you can try.

Resources