I would like to inject my service file into my controller using AngularJS so I can make the $http calls, but when I do so, I receive an error that it isn't defined.
Here's my service call in a separate file that has been included into the index.html.
(function () {
'use strict';
angular.module('App')
.service('MemberService', ['$http', '$q',
function MemberService($http, $q) {
var svc = this;
svc.postMembers = _postMembers;
var deferred = $q.defer();
_postMembers.$http({
method: 'POST',
url: '/api/MemberSearch',
data: data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(function (result) {
deferred.resolve(result)
}, function (error) {
deferred.reject(error);
});
return deferred.promise;
console.log("promise", deferred.promise);
}]);
})();
Now, here's the controller.js
(function () {
'use strict';
angular
.module('App')
.controller('MemberController', MemberController);
MemberController.$inject = ['$scope', '$http', '$q', 'MemberService', MemberService];
function MemberController($http, MemberService) {
var vm = this;
vm.search = {}; //a blank object to contain form data
vm.memberSearchForm = null; //reference to the actual form in html
vm.memberResult = []; //a blank object to handle returned data
vm.memberSearch = _memberSearch;
vm.showErrors = false;
function _memberSearch() {
vm.showErrors = true;
console.log("inside _memberSearch");
var promisePost = MemberService.postMembers(vm.search)
console.log("vm.search", vm.search);
}
};
})();
Any help is much appreciated.
Related
I am using AngularJs. When getting data from controller.js to service.js, I am getting the error. Below is the code used:
//controller.js
angular.module('testApp.controllers', []).
controller('testController', function ($scope, testAPIService, $timeout, $window, $location, $anchorScroll, $http) {
$scope.show = function() {
testAPIService.getDataSummary().success(function (response) {
console.log(response);
}).error(function (response) {
alert(response.responseText);
});
}
});
In Service.js
angular.module('testApp.services', []).
factory('testAPIService', ['$http', function ($http) {
var testAPIService = {};
testAPIService.getDataSummary = function () {
var request = {
url: urlBase + 'GetDataSummary',
method: 'Get',
headers: {
'accept': 'application/json'
}
}
return $http(request);
};
return testAPIService;
}]);
How to fix this? Thanks
This might be the result of including any of your app javascript file before the angularjs file.
Make sure you include angularjs file before the rest of your app files.
You're creating two different modules:
The first module testApp.controllers is created when you create the controller
Another module testApp.services is created when you create the service.
So the controller and the service are never part of the same module!
Try attaching to the same testApp module as follows:
app.js
// With [] means to create a new module.
angular.module('testApp', []);
controller.js
// Without [] means to retrieve an existing module.
angular.module('testApp').
controller('testController', function($scope, testAPIService, $timeout, $window, $location, $anchorScroll, $http) {
$scope.show = function() {
testAPIService.getDataSummary().success(function(response) {
console.log(response);
}).error(function(response) {
alert(response.responseText);
});
}
});
service.js
// Without [] means to retrieve an existing module.
angular.module('testApp').
factory('testAPIService', ['$http', function($http) {
var testAPIService = {};
testAPIService.getDataSummary = function() {
var request = {
url: urlBase + 'GetDataSummary',
method: 'Get',
headers: {
'accept': 'application/json'
}
}
return $http(request);
};
return testAPIService;
}]);
index.html
And change your ng-app directive to point to the testApp module
<html ng-app="testApp">
I try to use a service to get some data from server, but I had a problem: even the console log out the length when I print 'myData.length', when I try to find length of '$scope.test' controller variable it tell me that it is undefined.
What I should to do to use a $http service inside my own service?
app.controller('mainCtrl', ['$scope', 'mapServ',
function($scope, mapServ) {
$scope.test = [];
$scope.test = mapServ.test;
console.log('$scope.test = ' + $scope.test.length);
}]);
app.factory('mapServ', ['$http', function ($http) {
var path = "file path to my server data";
var out = {};
var myData = [];
out.test = $http.get(path).then(function (response) {
myData = response.data;
console.log(myData.length);
});
return out;
}]);
Take these service and controller as an example and you should follow John Papa's style guide while writing the code.
Service
(function() {
'use strict';
angular
.module('appName')
.factory('appAjaxSvc', appAjaxSvc);
appAjaxSvc.$inject = ['$http', '$q'];
/* #ngInject */
function appAjaxSvc($http, $q) {
return {
getData:function (path){
//Create a promise using promise library
var deferred = $q.defer();
$http({
method: 'GET',
url: "file path to my server data"
}).
success(function(data, status, headers,config){
deferred.resolve(data);
}).
error(function(data, status, headers,config){
deferred.reject(status);
});
return deferred.promise;
},
};
}
})();
Controller
(function() {
angular
.module('appName')
.controller('appCtrl', appCtrl);
appCtrl.$inject = ['$scope', '$stateParams', 'appAjaxSvc'];
/* #ngInject */
function appCtrl($scope, $stateParams, appAjaxSvc) {
var vm = this;
vm.title = 'appCtrl';
activate();
////////////////
function activate() {
appAjaxSvc.getData().then(function(response) {
//do something
}, function(error) {
alert(error)
});
}
}
})();
In your code you do not wait that $http has finished.
$http is an asynchronous call
You should do it like this
app.controller('mainCtrl', ['$scope', 'mapServ',
function($scope, mapServ) {
$scope.test = [];
$scope.test = mapServ.test.then(function(response) {
console.log(response.data);
}, function(error) {
//handle error
});;
}
]);
app.factory('mapServ', ['$http', function($http) {
var path = "file path to my server data";
var out = {};
var myData = [];
out.test = $http.get(path);
return out;
}]);
$http call that you are making from factory is asynchronous so it will not wait , until response come, it will move on to the next execution of the script, that is the problem only try Weedoze's asnwer, it is correct way to do this.
I have this factory:
(function () {
angular.module('appContacts')
.factory('dataService', ['$q', '$http', dataService]);
function dataService($q, $http) {
return {
getAllOrganizations: getAllOrganizations,
getAllContacts: getAllContacts,
};
function getAllContacts() {
return $http({
method: 'GET',
url: 'api/allcontacts'
})
}
function getAllOrganizations() {
return $http({
method: 'GET',
url: 'api/organizations'
})
}
}
})();
And I have this Controller:
(function () {
"use strict";
angular.module('appContacts')
.controller('contactsController', function contactsController($http, dataService) {
var vm = this;
vm.organizations = [];
vm.allcontacts = [];
vm.organizations = dataService.getAllOrganizations();
vm.allcontacts = dataService.getAllContacts();
});
})();
If I make a console.log in the controller like
console.log(dataService.getAllOrganizations()) and console.log(dataService.getAllContacts()) I see I have a PROMISE therefore I get an error like
[filter:notarray] Expected array but received: {}:
How could I convert this promise in a real error that I could assign to the variables like:
vm.organizations = dataService.getAllOrganizations()
and
vm.allcontacts = dataService.getAllContacts();
?
Your services return with promise. So, you need to resolve the promise using then syntax in the controller in order to get the data from your server. You need something like this:
dataService.getAllOrganizations().then(function(result){
vm.organizations = result;
}, function(error){
console.log(error);
});
In order to having your calls by default you need a method, let's call it activate(). I'm not sure the syntax is correct, I wrote it top of my head.
Please check John Papa's style guide here.
(function () {
"use strict";
angular.module('appContacts')
.controller('contactsController', function contactsController($http, dataService) {
var vm = this;
vm.organizations = [];
vm.allcontacts = [];
var activate = function activate() {
dataService.getAllOrganizations().then(function(result){
vm.organizations = result;
}, function (error){});
dataService.getAllContacts().then(function(result){
vm.allcontacts = result;
}, function (error){});
}
activate();
});
})();
I've got a function in an Angular controller like so:
(function () {
'use strict';
var controlledID = 'Clause.Clause';
angular.module('docapp').controller(controlledID, ['$scope', 'common', 'taskSvc', 'clauseSvc', Clauses]);
function Clauses($scope, clauseSvc, taskSvc, common) {
$scope.GetContractMaster = function GetContractMaster() {
clauseSvc.getAll()
.then(function (response) {
$scope.ContractMaster.rowData = response.d.results;
console.log(response.d.results);
});
};
$scope.GetContractMaster();
};
}
})();
My Services
(function () {
'use strict';
var app = angular.module('docapp');
app.factory("clauseSvc", ["baseSvc", function (baseService) {
var listEndPoint = '/_api/web/lists/';
var getAll = function () {
var query = listEndPoint + "GetByTitle('CLAUSE_MST')/Items?$select=Title,Title,Desc,nodes/ID&$expand=nodes";
return baseService.getRequest(query);
};
return {
getAll: getAll
};
}]);
})();
baseService
"use strict";
(function () {
angular.module("docapp")
.factory("baseSvc", ["$http", "$q", function ($http, $q) {
var baseUrl = _spPageContextInfo.siteAbsoluteUrl;
var getRequest = function (query) {
var deferred = $q.defer();
$http({
url: baseUrl + query,
method: "GET",
headers: {
"accept": "application/json;odata=verbose",
"content-Type": "application/json;odata=verbose"
}
})
.success(function (result) {
deferred.resolve(result);
})
.error(function (result, status) {
deferred.reject(status);
});
return deferred.promise;
};
return {
getRequest: getRequest
};
}]);
})();
Getting error
[true] [SYSERR] clauseSvc.getAll is not a function Object {exception:
TypeError: clauseSvc.getAll is not a function
at n.GetContractMaster
Need help
Your controller is declared as
.controller('$scope', 'common', 'taskSvc', 'clauseSvc', Clauses]);
and the function is declared as
function Clauses($scope, clauseSvc, taskSvc, common)
So, the variable clauseSvcis in fact the common service instance, and the variable common is in fact the clauseSvc service instance.
Do yourself a favor: avoid that kind of bugs and make your code easier to write and read by just avoiding this array syntax, and using ngAnnotate to make your code minifiable.
I have this simple factory that fetches a data file and saves it to service.data:
angular.module("tiki").factory("editTiki", ["$http", function($http){
var service = {}
service.data = {}
service.getTikis = function(){
$http.get("data/tikis.json").success(function(tikis){
console.log(tikis)
service.data = tikis
})
}
return service
}])
Then, in the controller i assign it to the $scope. This is first empty ofcourse but when the $http resolves it should update my factory and in turn update the service.data object with the returned data.
angular.module('tiki').controller("tiki.controller.settings.edit", ["$scope", "editTiki", function($scope, editTiki){
//should return the tikis
$scope.preview = editTiki.data
editTiki.getTikis()
$scope.showEditTikiObject = function(){
console.log($scope.preview)
}
}])
However, i have this function to test the contents of the data and it returns an empty object. Why is that?
You are reassigning service.data = tikis after assigning it to $scope.preview.
You should do probably something with the promise.
angular.module("tiki").factory("editTiki", ["$http", function($http){
var service = {};
service.data = {};
service.getTikis = function(){
return $http.get("data/tikis.json").success(function(tikis){
console.log(tikis)
service.data = tikis;
return service.data;
})
};
return service;
}]);
angular.module('tiki').controller("tiki.controller.settings.edit", ["$scope", "editTiki", function($scope, editTiki){
editTiki.getTikis()
.then(function () {
$scope.preview = editTiki.data;
});
$scope.showEditTikiObject = function(){
console.log($scope.preview);
};
}])
I ended up with the following. So here I am not injecting the scope object into the factory, but setting the $scope in the controller itself using the concept of promise returned by $http service. Hope this helps.
(function () {
getDataFactory = function ($http)
{
return {
callWebApi: function (reqData)
{
var dataTemp = {
Page: 1, Take: 10,
PropName: 'Id', SortOrder: 'Asc'
};
return $http({
method: 'GET',
url: '/api/PatientCategoryApi/PatCat',
params: dataTemp, // Parameters to pass to external service
headers: { 'Content-Type': 'application/Json' }
})
}
}
}
patientCategoryController = function ($scope, getDataFactory) {
alert('Hare');
var promise = getDataFactory.callWebApi('someDataToPass');
promise.then(
function successCallback(response) {
alert(JSON.stringify(response.data));
// Set this response data to scope to use it in UI
$scope.gridOptions.data = response.data.Collection;
}, function errorCallback(response) {
alert('Some problem while fetching data!!');
});
}
patientCategoryController.$inject = ['$scope', 'getDataFactory'];
getDataFactory.$inject = ['$http'];
angular.module('demoApp', []);
angular.module('demoApp').controller('patientCategoryController', patientCategoryController);
angular.module('demoApp').factory('getDataFactory', getDataFactory);
}());