// this is service where i m calling api
app.factory('users',['$http','$q', function($http , $q) {
return {
getUsers: function() {
var deferred = $q.defer();
var url = 'http://www.geognos.com/api/en/countries/info/all.jsonp?callback=JSONP_CALLBACK';
$http.jsonp(url).success(function (data, status, headers, config) {
console.log(data);
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
//this always gets called
console.log(status);
deferred.reject(status);
});
return deferred.promise;
}
}
}]);
//this is my controller where i calling getUsers();
app.controller('myCtrl', function($scope, users) {
$scope.data = users.getUsers();
})
while calling it gives me error
Uncaught ReferenceError: callback is not defined(anonymous function)
Plz give me proper solution so that i can see me api data in <div>. Thanks in advance
$http already returns a promise. There is no need to form a promise of a promise. Try this:
app.factory('Users', ["$http", function($http){
return {
getUsers: function(url) {
return $http({
url: url,
method: 'JSONP'
});
}
};
}]);
Controller:
app.controller("MyCtrl", ["$scope", "Users", function($scope, Users) {
$scope.data = [];
Users.getUsers('http://www.geognos.com/api/en/countries/info/all.jsonp?callback=JSONP_CALLBACK').then(function(response){
console.log(response.data);
$scope.data = response.data;
}).catch(function(response){
console.log(response.statusText);
});
}]);
Here the scenario is a bit different as you have to declare a $window.callback function.
Code
var app = angular.module("demoApp", []);
app.factory('UserService', ['$http', function ($http, $q) {
var getUsers = function () {
var url = 'http://www.geognos.com/api/en/countries/info/all.jsonp?callback=callback';
return $http.jsonp(url);
};
return {
GetUsers: getUsers
}
}]);
app.controller("demoController",
["$scope", "$window", "UserService",
function ($scope, $window, UserService){
UserService.GetUsers();
$window.callback = function (response) {
$scope.countries = response.Results;
}
}]);
Plunkr: http://plnkr.co/edit/MFVpj1sMqJpcDg3ZwQFb?p=preview
Related
I'm trying to learn AngularJS and need some help. I'm using version 1.4.9 and I'm trying to create a service that will get JSON from a server but I'm getting the following error: "serviceName is not defined"
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
Here is my service:
app.service('serviceName', function ($http, $q) {
var url= "myURL";
function getData() {
return $http.get(url);
}
return {
getData: getData,
}
}
);
Here is my controller:
app.controller("myController", function ($scope, $http) {
serviceName.getData().then(function (response) {
$scope.myField = response.data;
});
});
You need to inject your service into the controller, like this:
app.controller("myController", function ($scope, serviceName) {
serviceName.getData().then(function (response) {
$scope.myField = response.data;
});
});
And you do not need $http, because that's used in the service ;)
I have this factory:
'use strict';
angular.module('testCon').factory('UserService', function ($http) {
return {
getAll: function () {
return $http.get('http://localhost:1337/api/user');
}
}
});
And this controller:
'use strict';
angular.module('testCon').controller('UserController', function ($scope, UserService) {
$scope.users = [];
UserService.getAll().then(
function (data) {
$scope.users = data.data;
}, function (err) {
}
);
});
Can I somehow avoid the data.data I would like to have only data. What is it that forces me to do data.data in order to see it in the scope?
Simply you can't avoid that. You could make that as one time change by returning only a response.data from getAll method. Then all the consumer will get direct data.
Code
angular.module('testCon').factory('UserService', function ($http) {
return {
getAll: function () {
return $http.get('http://localhost:1337/api/user').then(function(response){
return response.data
});
}
}
});
You can try something like this:
'use strict';
angular.module('testCon').factory('UserService', function ($http) {
return {
getAll: function () {
return $http.get('http://localhost:1337/api/user').then(function (response) {
return response.data;
});
}
}
});
Then keep the other function as:
'use strict';
angular.module('testCon').controller('UserController', function ($scope, UserService) {
$scope.users = [];
UserService.getAll().then(
function (data) {
$scope.users = data;
}, function (err) {
}
);
});
What happens is that the first promise return is chained with the second then(..) but the second one gets the extracted data. It's a cool thing about promises.
I made an httpRequest fetch some items using following code:
factory.getBanners = function() {
$http({
method: 'GET',
url: 'http://localhost:2100/v1/items/getBanners'
}).then(function successCallback(response) {
console.log(response);
return response;
});
};
In controller I handled it as following:
store.controller('bannerCtrl', ['$scope', 'productService', function($scope, productService){
$scope.init = function() {
$scope.banners = productService.getBanners();
}
$scope.init();
}]);
In front end I tried to display data using
<div ng-controller="bannerCtrl">
<div data-ng-repeat="banner in banners">
<li> {{banner.bannerAltText}} </li>
</div>
</div>
But it doesn't display anything. Neither it gives any error on console. How can I resolve this issue. Here banners is an array whose each element contains bannerAltText.
Your getBanners-function does not work the way you think it does. It returns nothing. The return statement in the then function only returns from that then-function, not from getBanners. The problem is that you are trying to use an asynchonous function in a synchronous way. Instead make getBanners return a promise:
factory.getBanners = function() {
return $http({
method: 'GET',
url: 'http://localhost:2100/v1/items/getBanners'
}).then(function successCallback(response) {
return response.data;
});
};
And use that promise in your controller:
$scope.init = function() {
productService.getBanners().then(function(banners) {
$scope.banners = banners;
});
}
$scope.init();
A return in a in .then() will be a promise, rather than the data. here is a better way to construct your code
factory.getBanners = function() {
return $http({
method: 'GET',
url: 'http://localhost:2100/v1/items/getBanners'
});
};
.
store.controller('bannerCtrl', ['$scope', 'productService', function($scope, productService){
$scope.init = function() {
productService.getBanners()
.then(function(response) {$scope.banners = response.data});
}
$scope.init();
}]);
I'm developing my first AngularJS app using the Google Docs API to pass it JSON data.
This is an example of the factory I'm using:
app.factory('Data', ['$http', 'apiKeys', function($http, apiKeys){
var googleDocs = 'https://spreadsheets.google.com/feeds/list/';
return {
news:function () {
return $http.get(googleDocs + apiKeys.googleDoc +'/1/public/values?alt=json', {cache: true});
},
updates:function () {
return $http.get(googleDocs + apiKeys.googleDoc +'/2/public/values?alt=json', {cache: true});
},
docs:function () {
return $http.get(googleDocs + apiKeys.googleDoc +'/3/public/values?alt=json', {cache: true});
}
}]);
I wanted to clean up a bit the code and decided to use services instead of making the calls in the controller itself. It works normally, but it's a pain in the ass the fact that I still need to write long $scopes because of the structure of the Google API. This is how I get the values in the controller:
app.controller('homeCt', ['$scope', 'Data', function ($scope, Data){
Data.news().success(function (data) {
$scope.totalNews = data.feed.entry.length;
});
}]);
Is there a way that I can set the factory service to pass me the data just using:
$scope.totalNews = Data.news()
Or at least removing the 'feed.entry'?
Data.news().success(function (data) {
$scope.totalNews = data.length;
});
Thank you very much!
example of service - resolve the success with the data you want
app.service('Data', ['$http', 'apiKeys', function($http, apiKeys){
var googleDocs = 'https://spreadsheets.google.com/feeds/list/';
this.news =function(){
return $http.get(googleDocs + apiKeys.googleDoc +'/1/public/values? alt=json', {cache: true})
.then(function(data){
return data.feed.entry.length;
});
}
}]);
the controller - since you already resolved the data in service hence..
app.controller('homeCt', ['$scope', 'Data', function ($scope, Data){
Data.news().then(function (data) {
$scope.totalNews = data;
});
}]);
working example
var app = angular.module('app', ['ionic'])
.service('Data', ['$http',
function($http) {
var googleDocs = 'https://spreadsheets.google.com/feeds/list/1aC1lUSxKatfxMKEy1erKDSAKgijSWOh77FDvKWhpwfg/1/public/values?alt=json';
this.news = function() {
return $http.get(googleDocs, {
cache: true
}).then(function(res) {
return res.data.feed.entry;
});
}
}
])
.controller('homeCt', ['$scope', 'Data',
function($scope, Data) {
Data.news().then(function(data) {
console.log(data);
})
}
]);
I'll give you a way of doing it, a way that I don't recommend at all (a service should not handle the scope), but for me it is the only way you have if you don't want to destroy the "async" of your ajax call :
app.factory('Data', ['$http', 'apiKeys', function($http, apiKeys){
var googleDocs = 'https://spreadsheets.google.com/feeds/list/';
return {
news:news,
updates: updates,
[...]
}
function news(scopeValue) {
$http.get(googleDocs + apiKeys.googleDoc +'/1/public/values?alt=json', {cache: true}).success(function(data){
scopeValue = data;
});
}]);
and then, call it that way in your controller :
Data.news($scope.totalNews);
I've created a web application using the Hot Towel Angular template, and I want to add a service function to the 'datacontext'.
Code is:
(function () {
'use strict';
var serviceId = 'datacontext';
angular.module('app').factory(serviceId, ['common', '$http', datacontext]);
function datacontext(common, $http) {
var $q = common.$q;
var service = {
getFunctions: getFunctions
};
return service;
function getFunctions() {
var f = [];
$http({
method: 'GET',
url: 'https://api.github.com/users/google/repos',
contentType: 'application/json; charset=utf-8'
})
.success(function (data, status, headers, config) {
f = data;
console.log('f=*' + f + '*');
})
.error(function (data, status, headers, config) {
alert('error!');
});
return $q.when(f);
}
}
})();
I see that the console shows some objects:
f=*[object Object],[object Object],[object O...
But when using this in my functionController.js file :
function getFunctions() {
return datacontext.getFunctions().then(function (data) {
console.log('data=*' + data + '*');
return vm.functions = data;
});
}
The value for data is set to undefined.
I'm missing something, please help identify the error.
Solution:
The getFunctions function in the datacontext should return the $http promise object, like this:
function getFunctions() {
return $http.get('https://api.github.com/users/google/repos')
.error(function (data, status, headers, config) {
alert('error ! : ' + status);
});
}
And in the controller, you can use the returned json object as follows:
function getRepos() {
return datacontext.getRepos().then(function (httpResult) {
vm.repos = httpResult.data;
});
}