Calling service function from within the same service - javascript

I am trying to call a service method from within the same service but I am getting call to undefined function error. So I made a work around as shown below but still wondering how I can call the service function without using the work around. So can someone please help by telling me what I am missing here? Thanks
.factory('TestSvc', function($http, $q) {
return {
login: function(){
var checkStatusFunction = this.checkstatus; //This is the workaround to make it work...
$http({ method:'POST',
url: url
responseType: 'json'
}).success(function(data,status,headers,config){
//this.checkStatus(); //this will return error call to undefined
checkStatusFunction(); //this will work as it is the work around
}).error(function(data,status,headers,config){
});
},
checkStatus: function(){
}
}
});

A little bit less hacky would be:
var $this = this;
Instead of:
var checkStatusFunction = this.checkstatus;
And then call:
$this.checkstatus();

Related

Not able to call method under success of api using .bind(this)

I am trying to call method on success of my ajax api call. I have stored this(context) inside local variable that but still not able to get context of that view and getting error that.setPdfUrl is not a function. And important thing is i am calling method by pub/sub mechanism.
My code looks like -
kf.Events.off('getPdfUrl');
kf.Events.on('getPdfUrl', this.getPdfUrl);
getPdfUrl: function() {
var that = this;
$.ajax({
url: kf.Settings.fileGeneratorUrl() + "/ikfc/singlereport",
type: 'POST',
data: {
//content
},
success: function(result) {
that.setPdfUrl(kf.Settings.fileGeneratorUrl() + '/download?guid=' +
result.Message);
}
});
}.bind(this),
setPdfUrl: function(url){
this.pdfUrl = url;
}
Getting
Uncaught TypeError: that.setPdfUrl is not a function
I got solution by binding context at initialize -
kf.Events.on('getPdfUrl', this.getPdfUrl.bind(this))
You can just move following lines.
getPdfUrl: function() {
var that = this;
Change to
var that = this;
getPdfUrl: function() {
it will work, there are multiple ways to achieve this. but for now, you can use this.

AngularJS scope.apply causes error

I have this function which fetches data from the DB and updates scope's values.
$scope.loadFromDB = function(){
console.log("loadFromDB function");
$http({
url: '/getData',
method: "GET",
})
.then(function(response) {
// success
var data = JSON.parse(response.data)
data = JSON.parse(data.data)
$scope.gridDataDayData = data.dayData;
$scope.gridDataKlasoveNames = data.klasoveNames;
$scope.gridDataNumOfRows = data.numOfRows;
$scope.$apply();
},
function(response) { // optional
// failed
console.log("get unsuccessful");
});
};
When I run this though I get
error: [$rootScope:inprog] http://errors.angularjs.org/1.4.3/$rootScope/inprog?p0=%24digest
I can not figure out how to fix this. Please help me.
Thank you
You don't need trigger the digest cycle because you are inside the angular life cycle... it is already running.
A manual triggering is needed when you are outside from the angular way: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
Simply remove
var data = JSON.parse(response.data)
data = JSON.parse(data.data) and $scope.$apply()
and
$scope.$apply();

Angular async http autocomplete

I want to create an autocomplete with Angular and since this is my first contact with angular, I`m pretty stucked.
Here is my code:
MenuService.getAutocompleteData(term).then(function (response) {
$scope.menuData = response.data;
});
This is how I call a service that is making the following http call:
return $http({
url : autocompletePath,
method : "POST",
data : {
term: term
}
}).success(function (response) {
return response;
});
The problem is that it seems that is syncronously and my browser freezes when I type fast letters. I saw that it is about that ".then" promise, but I`m not sure how to fix it. Any help would be appreciated.
You do a HTTP-request, which is correct, but you try to return the result on success. Instead you should try to do what needs to be done in your success-handler.
So in your service you would do something like this:
return $http({
url : autocompletePath,
method : "POST",
data : {
term: term
}
}); //note that there is no success handler in your service, because what's supposed to happen when the request completes, is the controller's business, not the service's. The service should only know where to get the data
And you would change your controller to this:
MenuService.getAutocompleteData(term).success(function (response) {
$scope.menuData = response.data;
}); //note the success-handler
Why dont you give this a try?
https://angular-ui.github.io/bootstrap/#/typeahead

AngularJS : injecting data from factory to controller

I trying to get some data and then pass it to the controller for further processing. I have setup a factory to get the data but having issues passing it to the controller and getting it working. Below is the case I'm working with.
var app = angular.module("contactApp",[]);
app.factory('listData',function($http){
return{
getData: function(onSuccess,onFailure,itemID){
$http.get("/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20"+itemID).success(onSuccess).error(onFailure);
}
};
});
app.controller('ContactController', function(listData,$scope){
//setTimeout(function(){console.log(Data)},2000);
console.log("Controller called. Hello");
listData.getData(successFunction,failFunction,curItemId);
successFunction = function(data){
$scope.resData = data;
console.log("Success - ", data);
}
failFunction - function(data){
console.log("Didn't work - ", data);
}
});
This gives me below error.
successFunction is not defined
Not sure what I'm doing wrong, any input will be greatly appreciated!
EDIT:
Moving the functions down works really well but the async call is failing. I switched to using $ajax and it works just fine but $http doesn't work for some reason!
app.factory('listData',function($http){
return{
getData: function(onSuccess,onFailure,itemID){
//$http.get("/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20156").success(onSuccess).error(onFailure);
$.ajax({
url:"/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20"+itemID,
headers: {"accept": "application/json; odata=verbose"},
success: onSuccess,
error: onFailure
});
}
};
});
Just fyi the data is coming from a SharePoint list but that shouldn't matter. I'll keep digging and please do let me know if I'm making any syntax error that I can't locate.
I really appreciate the help guys!
EDIT 2:
Ok this issue was unrelated. I found the problem, SharePoint uses odata so I had to pass a header:
app.factory('listData',function($http){
return{
getData: function(onSuccess,onFailure,itemID){
$http(
{
method: "GET",
headers: {"accept": "application/json; odata=verbose"},
url: "/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20"+itemID
}
).success(onSuccess).error(onFailure);
}
};
});
You guys ROCK!!!!!!!
As Daniel A. White said, declare your functions before you call them.
var app = angular.module("contactApp",[]);
app.factory('listData',function($http){
return{
getData: function(onSuccess,onFailure,itemID){
$http.get("/_api/web/lists/getbytitle('Consultant%20Profile')/items?$filter=ID%20eq%20"+itemID).success(onSuccess).error(onFailure);
}
};
});
app.controller('ContactController', function(listData,$scope){
//setTimeout(function(){console.log(Data)},2000);
console.log("Controller called. Hello");
var successFunction = function(data){
$scope.resData = data;
console.log("Success - ", data);
}
var failFunction - function(data){
console.log("Didn't work - ", data);
}
//Now your functions are actually defined.
listData.getData(successFunction,failFunction,curItemId);
});
You don't have to use var to declare functions, because JavaScript will still understand but using var makes it a local variable, while not using var will define it as global.
I'm sure this will help.

Extend a function stored in a variable

I have a large JavaScript project that makes several Ajax web service calls. The code to handle the web service calls comes from a shared external file.
To separate the web service from calling code, there is a global object to reference to the calling function like so
var doRemote ={};
$(document).ready(function(){
doRemote =getRemoteEndpoint('https://someplace.org/MyWebService.aspx');
}
A simplified version of the getRemoteEndpoint, which is in a file shared by several other pages in addition to the one I'm working on is as follows:
function getRemoteEndpoint(url) {
return function(methodName, options) {
var extension = {
url: url + '/' + methodName,
data: {},
async: true
};
var combined = $.extend({}, extension, options);
combined.data = JSON.stringify(combined.data);
return $.ajax( combined );
};
}
I invoke the web service calls by the following code
doRemote('WebServiceMethodName',
{
success: function(data) {
alert('Web Service Returned' + data);
},
error: function(req, stat, err) {
alert('Error');
}
});
I have the need to execute a function before executing the getRemoteEndpoint call in only the page I'm working on. Instead of calling the function before each of the 30 web service calls, I'd like to add a line of code to the function. I've tried to replace the doRemote assignment with the following.
doRemote =function() {
DoTask();
return getRemoteEndpoint('https://someplace.org/MyWebService.aspx');
};
DoTask is a named function in the program I'm working on. While it throws no errors, none of the Ajax calls work.
I tried to use the JQuery.extend function, but it didn't work either.
What am I doing wrong?
You have to actually call it to assign the result of getRemoteEndpoint to doRemote:
doRemote = (function() {
DoTask();
return getRemoteEndpoint('https://someplace.org/MyWebService.aspx');
})();
Update:
doRemote = (function() {
var oldDoRemote = getRemoteEndpoint('https://someplace.org/MyWebService.aspx');
return function(a1, a2) {
DoTask();
oldDoRemote(a1, a2);
}
})();

Categories