In my console the error is coming "getIdData is not defined" what is wrong with my code. Here deal is my service and getIdData is my function in service.
$scope.editUserDetail = function editUserDetail(){
$scope.showEditView = !$scope.showEditView;
$scope.showSubmitView = !$scope.showSubmitView;
console.log(deal);
deal.getIdData().then(function successCb(data){
$scope.editIdOptionsData=data;
});
};
Please check working example here: Demo
You are forget to return service object from service.
i.e
Write following code in your service,
return service;
i.e
angular.module('account').service('deal', function deal($http, accountConfiguration, $q, $log, httpHelper) {
var service = {};
var baseUrl = account.app.url;
service.getIdData = function(data, accountId, decisionMakerDetail) {
var def = $q.defer();
var url = baseUrl + '/api/accountsusers/' + accountId + '?role=' + decisionMakerDetail;
httpHelper._$http({
method: 'post',
url: url,
data: data,
def: def
}, function(resp) {
def.resolve(resp.msg);
});
return def.promise;
};
return service;
});
Or as you are using service you can write it using this
angular.module('account').service('deal', function deal($http, accountConfiguration, $q, $log, httpHelper) {
var baseUrl = account.app.url;
this.getIdData = function(data, accountId, decisionMakerDetail) {
var def = $q.defer();
var url = baseUrl + '/api/accountsusers/' + accountId + '?role=' + decisionMakerDetail;
httpHelper._$http({
method: 'post',
url: url,
data: data,
def: def
}, function(resp) {
def.resolve(resp.msg);
});
return def.promise;
};
});
For more information please check - Services
Please clean your browser and inspect source.Look deal.getIdData() is loaded or not.May be it is not loaded.Please load properly.
The object you are sending as a parameter doesn't have the getIdData() function defined.
Change your log to:
console.log(deal.getIdData);
and then check whether it returns the function code/definition.
Here is a link with an example of how implement a factory and service.
Angular factory and service
You are not returning the object holding the service reference from you your service registration function. Change your code as below for it to work.
angular.module('account')
.service('deal', function deal($http, accountConfiguration, $q, $log, httpHelper) {
var service = {};
var baseUrl = account.app.url;
service.getIdData = function(data,accountId,decisionMakerDetail){
var def = $q.defer();
var url = baseUrl + '/api/accountsusers/' + accountId + '?role=' + decisionMakerDetail;
httpHelper._$http({
method: 'post', url: url, data: data, def: def
}, function (resp) {
def.resolve(resp.msg);
});
return def.promise;
};
return service;
});
S8nce you were not returning anything from the service, even though deal service gets registered, its value is undefined and when you try to access deal.getIddata() you get the aforementioned error
Related
I have a factory which makes a call to the API using AJAX like so
App.factory("DashboardData", function($q) {
method = 'POST';
var fetchDataFromApi = function(url, data) {
code = null;
response = null;
return $.ajax({method: method, url: url, dataType: 'json', data: data}); };
return {
counters: function() {
var deferred = $q.defer();
return data = fetchDataFromApi('http://solmon.belgiumcampus.ac.za/api/data/getdashboarddata');}
};});
I then have a controller which calls to this factory and populates an array with the response that it receives like so
App.controller("DashboardWidgets", function($scope, DashboardData) {
var response = DashboardData.counters();
$scope.CounterData = [];
response.then(function(response) {
$scope.CounterData = [
response.onlineUnits,
response.offlineUnits,
response.overallVoltage,
response.overallCurrent,
response.maintenanceUnits
];
});
alert("Online from controller: " + $scope.CounterData[0]);});
If I take out the alert at the end then the DOM element does not display the data that is received. Why is this happening and how would you recommend I fix it?
EDIT : i get an error like this when i last checked in browser console.
TypeError: Cannot read property 'defer' of undefined
I need to call one $http request which gives the token that can be used to call another $http request and finally the required response.
Hence i am using promises to make it work synchronously.However the function does not get executed after the $q.defer() function
Following is my code:
$scope.firstTimeAuth = function($q) {
var deferred = $q.defer();
var ref = window.open('https://accounts.google.com/o/oauth2/auth?client_id=' + clientId + '&redirect_uri=http://localhost/callback&scope=https://www.googleapis.com/auth/fitness.activity.write &approval_prompt=force&response_type=code&access_type=offline', '_blank', 'location=no');
ref.addEventListener('loadstart', function(event) {
if((event.url).startsWith("http://localhost/callback")) {
requestToken = (event.url).split("code=")[1];
$http({
method: "post", url: "https://accounts.google.com/o/oauth2/token",
data: "client_id=" + clientId + "&client_secret=" + clientSecret + "&redirect_uri=http://localhost/callback" + "&grant_type=authorization_code" + "&code=" + requestToken
})
.success(function(data) {
defer.resolve(true);
accessToken = data.access_token;
refreshToken = data.refresh_token;
alert("firstTimeAuth success");
if(typeof(Storage) != "undefined") {
localStorage.setItem("refreshToken",refreshToken);
alert(localStorage.getItem("refreshToken"));
} else {
alert("Sorry, your browser does not support Web Storage...");
}
//functions here
})
.error(function(data, status) {
alert("ERROR: " + data);
defer.resolve(true);
});
ref.close();
}
});
return deferred.promise;
}
This is my second function
$scope.getAcessToken = function($q)
{
var deferred = $q.defer();
alert("inside getAcessToken function");
refreshToken = localStorage.getItem("refreshToken");
if(refreshToken)
{
$http({
method: "post", url: "https://accounts.google.com/o/oauth2/token",
data: "client_secret=" + clientSecret + "&grant_type=refresh_token" + "&refresh_token="+ refreshToken + "&client_id=" + clientId
})
.success(function(data){
accessToken = data.access_token;
alert("getAcessToken success" + accessToken);
deferred.resolve(true);
})
.error(function(data,status){
alert("ERROR: " + JSON.stringify(data) + status);
deferred.resolve(true);
});
}
else
{
$scope.firstTimeAuth();
}
return deferred.promise;
}
and i call them like this.
alert("not installed");
var lastSaved = $scope.getFirstEpochTime();
//walkthroug
//Registe
$scope.firstTimeAuth().then(function(){
alert("firstime done");
$scope.getDataSets().then(function(){
alert(" in the last block");/*
$scope.handleResponse().then(function(){
$scope.insert().then(function(){
$scope.select();
})
alert("done in installed");
})
*/})
})
Please let me know what is wrong with the code. i am very new to this.. thanks.
Are you injecting $q in your controller at first place.
angular.module('module.name').controller('ControllerName',
['$scope', '$q', function ($scope, $q) {
}]);
I am not really getting why are you passing $q to your function, you don't need that to be. $scope.firstTimeAuth = function($q) {
By defining a parameter for a function, you're creating a local variable which hides anything with the same name in outer scope. In your case you're defining:
$scope.firstTimeAuth = function($q) {}
And then you're invoking it like $scope.firstTimeAuth(); in many places. Since you don't pass anything, $q in the functions scope will be undefined. You should only inject it in the entire controller scope and remove such parameters specified in scope methods so that it doesn't hide the injected service.
Or if you must pass them around for some reason, do it properly.
how to access the response inside controller from a nested $http which is inside a factory. here we are having two service calls.one inside another.I need the response of the second service call in my controller. I am able to access the factory from controller and also the response inside the factory but when comes to controller success function, it's showing success function is not defined.
factory code : here i am calling nested $http service calls
bosAppModule.factory("ServiceCalls",function($http){
var ServiceCalls={};
var createFilterString = function(crudObject, callback) {
var filterString = "";
var keyValuePairs = [];
// iterate over the property
for(var property in crudObject) {
if(!(crudObject[property] instanceof Object)) {// if it is primitive type
// check the value is not null or undefined
if(crudObject[property] && crudObject[property] != "")
// added the key value string
keyValuePairs.push(property + "~;~" + crudObject[property]);
}
}
// add first key value pair
if(keyValuePairs[0])
filterString += keyValuePairs[0];
// iterate over the key value strings
for(var i = 1; i < keyValuePairs.length; i++) {
filterString += "~$~" + keyValuePairs[i];
}
try {
if(callback) callback(filterString);
} catch(e) {
console.log("Exception inside $dataTransactor->createFilterString" + e.message);
}
};
// var headers = {Authorization: COOKIES.readCookie("Authorization"),requestmode:"ACK_URL"};
// headers.isRender = file.isRender;
// if(file.inputDataHeaders)
// headers.inputData = file.inputDataHeaders;
ServiceCalls.getData = function(filterObject, file){
createFilterString(filterObject, function(filterString){
var headers = {Authorization: COOKIES.readCookie("Authorization"),requestmode:"ACK_URL"};
headers.isRender = file.isRender;
if(file.inputDataHeaders)
headers.inputData = file.inputDataHeaders;
$http({
method: 'GET',
url: file.fileUrl + "/" + $securityComponent.cryptograghicFunctions.encryptor(filterString),
headers: headers
})
.then(function(requestHandlerResponce) {
console.log(requestHandlerResponce);
$http({
method: 'GET',
url: requestHandlerResponce.data.links[1].href,
headers: headers
}).then(function(responceHandlerResponce) {
console.log("##### : "+JSON.stringify(responceHandlerResponce.data));
return responceHandlerResponce;
});
})
});
};
return ServiceCalls
});
controller code : here I need the response
bosAppModule
.controller(
"custom-entity-design-ctrl",
function($scope, $document, $http, $localStorage, navigateEntityUrl, entityFormation,layoutDesignFactory, ServiceCalls) {
var layoutDesignFac=new layoutDesignFactory();
var entityJson='{"entityInfo":{"entity":"","tenantId":"2b69af63-e2dc-43e5-9f0e-9fde52032d4c","timeStamp":"Tue Jun 16 2015 19:05:09 GMT+0530 (India Standard Time)"},"collections":{"Entity":{"meta":{"parentReference":"***","pkName":"***","fkName":"***"},"rowSet":[],"rowFilter":[]}}}';
var crudObject = {};
var file = {
fileUrl: $config.UIMetaData,
inputDataHeaders: entityJson
};
ServiceCalls.getData(crudObject,file).success(function(response){console.log(response)});
});
Your services should be returning the promises (the $http call in your case) to the controller:
return $http({ // return this promise
method: 'GET',
url: file.fileUrl + "/" + $securityComponent.cryptograghicFunctions.encryptor(filterString),
headers: headers
}).then(function(requestHandlerResponce) {
console.log(requestHandlerResponce);
return $http({ // return this promise as well
method: 'GET',
url: requestHandlerResponce.data.links[1].href,
headers: headers
}).then(function(responceHandlerResponce) {
console.log("##### : "+JSON.stringify(responceHandlerResponce.data));
return responceHandlerResponce;
});
And just to be consistent try to use the standard .then method rather than .success or .error in your controller:
ServiceCalls.getData(crudObject,file).then(function(response) {
console.log(response)
});
Last somewhat irrelevant note, I think 'response' is misspelled in your service ;)
I am trying to use POST with $resource object in my app.
I have something like this.
Factory:
angular.module('toyApp').factory('toys', ['$resource', function ($resource) {
return $resource('/api/v1/toy/:id/condition/:condid',
{ id: '#id',
condid: '#condid' }
);
}]);
Controller:
$scope.addNew = function() {
//how do I pass id and condid below?
toys.save({'name': 'my first toy'});
})
The above code will pass url like
/api/v1/toy/condition/
I need to send the request url like
/api/v1/toy/6666/condition/abd with parame {'name': 'my first toy'}
How do I do it?
Thanks for the help!
It's very clearly described in the API reference:
https://docs.angularjs.org/api/ngResource/service/$resource
What $resource(url) returns is a class object. If you want to create a new instance and save it, you'll call the $save method on the instance:
var Toy = $resource('/api/v1/toy/:id/condition/:condid',
{id: '#id', condid: '#condid'});
var toy = new Toy({'id': 123, 'condid': 456, 'name': 'my first toy'});
toy.$save();
But if you want to call an object creation API, you'll have to add a custom method to your resource:
var Toy = $resource('/api/v1/toy/:id/condition/:condid',
{id: '#id', condid: '#condid'},
{createToy: {method: 'POST', url: '/create-toy'}});
Toy.createToy({name: 'Slingshot'});
var newToy = new Toys({id: '6666', condid: 'abd'});
newToy.name = 'my first toy';
newToy.$save();
Try this
$scope.addNew = function() {
toys.save({'id': 'foo', 'condid': 'bar'});
})
You are correct in extrapolating $http controller logic to a service/factory.
Create a method to set the object that you will send with the HTTP POST request. Another method to set the url may also be created. The controller will then call these methods before saving to set the url and object to be used for the HTTP call. A dynamic url may be specified in the controller (with unique id and other fields as necessary) and sent to the service.
Service code:
var dataObj = [];
var myUrl = "";
//called from controller to pass an object for POST
function setDataObj(_dataObj) {
return dataObj = _dataObj;
};
function setUrl(_url) {
return myUrl = _url;
}
function saveToy() {
//if sending a different type of obj, like string,
//add "headers: { 'Content-Type': <type> }" to http(method, url, header)
$http({ method: 'POST', url: myUrl })
.then(function(data) {
return data;
})
.catch(function(error) {
$log.error("http.post for saveToy() failed!"); //if log is added to service
});
};
Controller code:
$scope.id = 574; //or set somewhere else
$scope.condid = 'abd';
$scope.objectYouWantToSend = [{"toyName": "Teddy"}];
// to obtain dynamic url for /api/v1/toy/:id/condition/:condid
$scope.url = '/api/v1/toy/' + $scope.id + '/condition/' + $scope.condid;
$scope.addNewToy = function() {
toyService.setUrl(url); //set the url
toysService.setDataObj($scope.objectYouWantToSend); //set the dataObj
toysService.saveToy(); //call the post method;
};
John Papa's AngularJS style guide is well put together and covers scenarios in multiple formats. Below is a link to the data-service factory section:
https://github.com/johnpapa/angular-styleguide#separate-data-calls
I am stuck on some problems , actually I was in problem solved , the problem was header which is not enableing to get response (like CORS issue) ,overcome by using header and transformRequest as shown in below code. After that I got webservice data but in one controller used $rootscope which render some of id of data of second method (API) to use in another controller to put on third one api to get data and I am getting this for only a minute then it will throw error : Cannot read property 'companies data' of null which is field in third api. when I used $rootScope.Test.companies[0].companyname which is store data, and unique for all api like primary key.
var request = $http({
method: "post",
url: "http://app.xyz/xyzapp/public/user/login",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
str.push(encodeURIComponent('email_id') + "=" + encodeURIComponent('demo#xyz.com'));
str.push(encodeURIComponent('password') + "=" + encodeURIComponent('demo#xyz'));
return str.join("&");
},
});
request.success(function( response ) {
console.log("Hiiiii::::"+JSON.stringify(response,status));
if (response.status=="success"){
$rootScope.Test1=response.user_id;
var request1 = $http({
method: "post",
url: "http://app.xyz/xyzapp/public/company/getUserCompanyList",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
str.push(encodeURIComponent('user_id') + "=" + encodeURIComponent(response.user_id ));
// str.push(encodeURIComponent('password') + "=" + encodeURIComponent('demo#123'));
return str.join("&");
}
});
// getCompany
request1.success(function( response ) {
console.log("Hiiiii::::"+JSON.stringify(response,status)+" "+response.companies.length+":Length");
if (response.status=="success"){
// alert(1);
$state.go('tabdash');
$rootScope.Test = response;
}
});
So please tell me how to use one controller data to another where I am using another api which will get $rootscope date of parent.
Please let me know if anybody know about that or anything
Thanks
Yes you can use variables of one controller inside another controller using two methods
Create Service to communicate between them.
Use $rootScope.$broadcast
sample code
angular.module('myservice', []).service('msgBus', function() {
this.serviceValue= {};
}]);
});
and use it in controller like this:
controller 1
angular.module('myservice', []).controller('ctrl1',function($scope, msgBus) {
$scope.sendmsg = function() {
msgBus.serviceValue='Hello';
}
});
controller 2
angular.module('myservice', []).controller('ctrl2',function($scope, msgBus) {
$scope.checkValue(){
alert( msgBus.serviceValue);
}
});