how to convert AJAX $http call to Angular.JS - javascript

For a functionality that I need, I found a really nice AJAX example. Basically it calls the Yahoo API. But I'm working with Angular.JS. So I have no clue how to convert that. Any help?
That's the AJAX function (details see this posting and this JsFiddle):
$.ajax({
type: 'GET',
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'YAHOO.Finance.SymbolSuggest.ssCallback',
data:{
query: request.term
},
url: 'http://autoc.finance.yahoo.com/autoc',
success: function (data) {
alert("yes");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
So what I'm looking for, is how to convert the code above into somewhat like this. The sample should just print the return value. See this JsFiddle. Especially, I have not idea what to do with the jsonpCallback parameter. That's what I could not find in any other example.
<div ng-app='MyModule' ng-controller='DefaultCtrl'>
{{ test() }}
</div>
JavaScript
function DefaultCtrl($scope, myService) {
$scope.test = myService.test;
}
angular.module('MyModule', [])
.factory('myService', function () {
return {
test: function () {
$http.get("?????")
.success(function(data, status, headers, config) {
return data;
})
.error(function(data, status, headers, config) {
return "there was an error";
})
}
}
});
The intermediate solution - after all your help - looks like this. Thanks. I had to install a Chrome extension which allows cross-domain calls as long as you use the updated JsFiddle. I changed the way I'm passing the parameters to the http-get call and I also included the $q (promise) handling. The result contains a valid list from Yahoo YQL API. Just need to handle that array then.
function DefaultCtrl($log, $scope, $http, myService) {
var promise = myService.getSuggestions('yahoo');
promise.then(
function(payload) {
$scope.test = payload;
$log.info('received data', payload);
},
function(errorPayload) {
$log.error('failure loading suggestions', errorPayload);
});
}
angular.module('MyModule', [])
.factory('myService', function ($http, $log, $q) {
return {
getSuggestions: function (symbol) {
var deferred = $q.defer();
$http.get('http://d.yimg.com/autoc.finance.yahoo.com/autoc', {
cache: true,
params: {
query: symbol,
callback: 'YAHOO.Finance.SymbolSuggest.ssCallback'
}
})
.success(function(data) {
deferred.resolve(data);
})
.error(function(msg, code) {
deferred.reject(msg);
$log.error(msg, code);
});
return deferred.promise;
}
}
});

just have a look at the docs
https://docs.angularjs.org/api/ng/service/$http
$http.get('http://autoc.finance.yahoo.com/autoc',
{dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'YAHOO.Finance.SymbolSuggest.ssCallback'}).success(function(data){ alert("yes"); });

Use Ajax call and you have to use promise
And use only test not {{test()}}
Because in your controller when you call your factory ajax function then in controller you get undefined response.
So use promise.
Service:
var demoService = angular.module('demoService', [])
.service('myService',['$http', function($http) {
this.getdata = function(entity){
var promise = $http({
method : 'GET',
url : 'services/entity/add',
data : entity,
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'YAHOO.Finance.SymbolSuggest.ssCallback',
headers : {
'Content-Type' : 'application/json'
},
cache : false
}).then(function (response) {
return response;
});
return promise;
};
}]);
Controller :
var demoService = angular.module('demoService', [])
.controller('myctr',['$scope','myService',function($scope,myService){
myService.getdata().then(function(response){
//Success
},function(response){
//Error
});
}]);
now you can see your json in controller success

Related

How to get promise result using AngularJS

The following is the controller used to retrieve information from sharepoint. I can see debugging that the entry data.d.UserProfileProperties.results[115].Value has a property value that I need to render in view. How can I get that value from the result promise?
(function() {
'use strict'
var createPurchasingCardController = function($scope, $rootScope, $filter, $window, $location, $timeout, requestService) {
$scope.actionTitle = "";
$scope.counter = [];
var getCurrentUserData = function () {
var dfd = new $.Deferred();
var queryUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetMyProperties";
$.ajax({
url: queryUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: onSuccess,
error: onError,
cache: false
});
function onSuccess(data) {
dfd.resolve(data);
}
function onError(data, errorCode, errorMessage) {
dfd.reject(errorMessage);
}
return dfd.promise();
}
var _init = function () {
$scope.counter = getCurrentUserData();
console.log($scope.counter);
}
_init();
}
angular.module('myApp').controller('createPurchasingCardController', ['$scope', '$rootScope', '$filter', '$window', '$location', '$timeout', 'requestService', createPurchasingCardController]);
}());
I have tried to get it into the counter but it is not showing up. Any help would be appreciated.
Instead of using jQuery .ajax, use the $http service:
function getCurrentUserData() {
var queryUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetMyProperties";
var promise = $http({
url: queryUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
cache: false
}).then(function(response) {
return response.data;
}).catch(function(response) {
console.log("ERROR", response);
throw response;
});
return promise;
}
Then extract the data from the returned promise:
function _init() {
var promise = getCurrentUserData();
promise.then(function(data) {
$scope.counter = data;
console.log($scope.counter);
});
}
_init();
The promises returned by the $http service are integrated with the AngularJS framework. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc.
For more information, see
AngularJS $http Service API Reference
assign your response object to $scope object
function onSuccess(data) {
$scope.promiseData = data
dfd.resolve(data);
}

AngularJS - Best approach for taking data from factory and if not there use http service

In my angularJS application, I have set data received from one controller's ajax and put in factory method to reuse in other controllers. The problem is when user reload page, this factory method is useless.
app.factory('factory', function () {
return {
set: set,
get: get
}
});
app.controller ('testController', function ($scope, factory) {
if (factory.get('name')) {
$scope.name= factory.get('name');
} else {
$http.get(url).then(function(res) {
$scope.name= res.name;
factory.set('name', res.name);
});
}
});
What is the best way to retrieve this check in factory method which will get value from factory, if not there take from http service and in controller common code needs handle these two cases that done factory method?
Here when data taken from http service it returns promise otherwise plain value.
This code will fetch data from server if the 'cachedResult' variable is not set, otherwise return a promise from the stored variable.
app.factory('factoryName', ['$http','$q', function($http,$q) {
var cahedResult = null;
var myMethod = function(args) {
var deferred = $q.defer();
if (cahedResult){
deferred.resolve({ data : cahedResult });
return deferred.promise;
}
$http.get(....).then(function(response){
cahedResult = response.data;
deferred.resolve({ data : cahedResult });
},function(error){
deferred.reject('error');
});
}
};
return {
myMethod : myMethod
}
])
But you could also store the data in local storage or in a cookie when the first controller fetch the info so that it's available even if user refresh the browser.
First create a factory :
app.factory('factoryName', ['$http','$q', function($http,$q) {
return {
getData : function(arg1,arg2) {
return $http.get('/api-url'+arg1+'/'+arg2)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data;
} else {
return $q.reject(response.data);
}
}, function(response) {
return $q.reject(response.data);
});
}
}
}])
Provide every api details in this factory, so you can use this factory in multiple controllers.
In Controller inject the factory (factoryName) as a dependency.
app.controller ('testController',['$scope', 'factoryName', function($scope, factoryName) {
factoryName.getData(arg1,arg2,...)
.then(function(data) {
console.log(data);
}, function(error){
console.log(error);
});
}]);
For detailed description :- http://sauceio.com/index.php/2014/07/angularjs-data-models-http-vs-resource-vs-restangular/
Directly return a promise from your factory
app.factory('factoryName', function () {
var connectionurl ='...'; //Sample: http://localhost:59526/Services.svc
return {
connectionurl : connectionurl ,
methodName: function (parameters) {
$http({
method: 'GET',
url: connectionurl + 'servicemethod_name'
})}
}
}
});
In this case your controller will look like
app.controller ('testController', function ($scope, factoryName) {
factoryName.methodName(parameters).then(function(){
$scope.variable=response.data;
/*binding your result to scope object*/
}, function() {
/*what happens when error occurs**/
});
});
Other way is directly bind to a scope object through success callback function
app.factory('factoryName', function () {
var connectionurl ='...'; //Sample: http://localhost:59526/Services.svc
return {
connectionurl : connectionurl ,
methodName: function (parameters,successcallback) {
$http({
method: 'GET',
url: connectionurl + 'servicemethod_name'
}).success(function (data, status, headers, config) {
successcallback(data);
})
.error(function (data, status, headers, config) {
$log.warn(data, status, headers, config);
});
}
}
});
In this case your controller will look like
app.controller ('testController', function ($scope, factoryName) {
factoryName.methodName(parameters,function(response){
/* your success actions*/
$scope.variable=response;
});
});
In the second case your error is handled in the factory itself. How ever you can also use errorcallback function.

not getting data from $http from service to scope

we are trying to get data from service agrService with $http its working but when i reccive data to controller i am not able to access it outside that function
$scope.resource return data inside function but not outside please help.
var app = angular.module('app', ['ui.router','ngTasty']);
app.config(['$urlRouterProvider', '$stateProvider',function($urlRouterProvider, $stateProvider, $routeProvider, $locationProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'templates/home.html',
controller: function($scope, $http, $location, agrService) {
agrService.bannerSlides().then(function(data) {
//its working here
$scope.resource = data;
}, function(error) {
// do something else
});
I NEED TO ACCCESS DATA HERE CAN ANY BODY HELP
console.log($scope.resource);
}
});
}]);
app.service('agrService', function($q, $http) {this.bannerSlides = function() {
var dataUrl = 'http://WWW.EXP.COM/codeIgniter_ver/main/home';
var ret = $q.defer();
$http({
method: 'GET',
dataType: "json",
url: dataUrl
})
.success(function(data, status, headers, config) {
ret.resolve(data);
}).error(function(data, status, headers, config) {
ret.reject("Niente, Nada, Caput");
});
return ret.promise;
};
});
My suggestion would be to rethink the logic a bit. You want to do something with the data after you receive it, so why not make a function that you call once the data is received?
You'll never be able to access the resource data in that console log, simply because $http is an async call, and no matter if you return a promise or not, it's simply not ready at that point.
However, if you use it in a template or elsewhere that uses angular's double binding, it will work just fine.
To fix your issue, you can define a function with what happens after that service call and simply call it from the success callback:
agrService.bannerSlides().then(function(data) {
//its working here
$scope.resource = data;
myAfterFunction(); // <--- here
}, function(error) {
// do something else
});
and the function can be:
function myAfterFunction() {
console.log($scope.resource);
}
And btw. your service is an example of deferred antipattern, you can simply do this:
app.service('agrService', function($q, $http) {this.bannerSlides = function() {
var dataUrl = 'http://WWW.EXP.COM/codeIgniter_ver/main/home';
return $http({
method: 'GET',
dataType: "json",
url: dataUrl
})
};
});

ngResource query returns strange objects

I am new to AngularJS and wanted to try out the $resource functionality.
I have this code:
.factory('GetTasksService', function($resource, BASE_URL) {
return $resource(BASE_URL + 'api/tasks');
})
.controller('TasksCtrl', function ($scope, $http, BASE_URL, GetTasksService) {
$scope.tasks = GetTasksService.query();
$scope.getTasks = function () {
$http({ url: BASE_URL + 'api/tasks', method: 'GET' })
.success(function (data, status, headers, config) {
$scope.tasks = data;
})
.error(function (data, status, headers, config) {
alert("call did not work");
});
}
});
The getTasks function works as expected - returning an array of:["taska", "taskb"] as it should.
The GetTasksService.query() however returns an array of [{"0":"t","1":"a","2":"s","3":"k","4":"a"}, {"0":"t","1":"a","2":"s","3":"k","4":"b"}]
Can anyone tell me what I am doing wrong?
There is an option when specifying an action for an ngResource called isArray;
The default action query sets this as true by default, so you need to set set the action like:
query : {
method : 'GET',
isArray : false
}

How to implement ajax call using promise with angular?

I'm trying to use angular promise using $q that is wrapped in 'service' and call it from my controller.
Here is the code:
var myController = function ($scope, myService) {
$scope.doSomething = function (c, $event) {
$event.preventDefault();
myService.method1(c).then(function (rslt) {
alert(rslt);
}, function (err) {
alert(err);
}).then(function () {
//clean up
});
};
};
var myApp = angular.module('myApp', [])
.factory('myService', function($q) {
function _method1(c) {
var dfr = $q.defer();
var dt = { sc: c };
$.ajax({
type: "POST",
url: "mypage.aspx/mymethod",
data: JSON.stringify(dt),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
dfr.resolve('actions sucess');
},
error: function (msg) {
dfr.reject(msg);
}
});
return dfr.promise;
}
return { method1: _method1 };
}).controller('myController', myController);
The problem is that ' alert(rslt);' piece of code is never executed.
Service is called and data is updated but first 'then' function is not reached on first click.
What am I doing wrong?
Any help appreciated.
I would recoomend you to use $http and $resource instead of $.ajax
Heres an example of $http
myApp.factory('MyService',
[
'$http',
'$q',
'$resource',
function (
$http,
$q,
$resource
) {
return {
doSomething : function (somedata) {
var deferred = $q.defer();
$http({ method: 'POST', url: '"mypage.aspx/mymethod"', data: somedata }).
success(function (data, status, headers, config) {
deferred.resolve(true);
}).
error(function (data, status, headers, config) {
deferred.resolve(false);
});
return deferred.promise;
}
};
}]);
Just add the dependency to $rootScope and call $rootScope.$apply() in both callbacks from $.ajax():
success: function () {
dfr.resolve('actions sucess');
$rootScope.$apply();
}, ...
But better yet, use Angular's $http service.

Categories