Im creating a custom service, where it is working, is returning me in the function service the data, the problem is when i call it in the controller, it is returning me 'undefined'.
Service:
var toDoListServices = angular.module('toDoListServices', []);
toDoListServices.factory('DataTasksService', function($http){
return {
getTasks: function(){
$http.get('js/data.json').success(function(data){
return data;
})
}
}
});
Controllers:
var toDoListController = angular.module('toDoListController', []);
toDoListController.controller('ListController', ['$scope', 'DataTasksService', function($scope, DataTasksService){
$scope.tasks = DataTasksService.getTasks();
}]);
App.js:
var myApp = angular.module('myApp', [
'ngRoute',
'toDoListController',
'toDoListServices'
]);
getTasks doesn't return anything. A return inside success does nothing.
You need to return the $http promise.
Try
toDoListServices.factory('DataTasksService', function($http){
return {
getTasks: function(){
// return the promise
return $http.get('js/data.json');
}
}
});
In controller:
DataTasksService.getTasks().then(function(response){
$scope.tasks = response.data;
});
Related
I tried to call function defined in a service.
var app = angular.module('title', ['flash', 'ngAnimate', 'ngRoute'],
function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
})
.service('getWidgets', function (globalServices, $http) {
var getData = function() {
var getWidgetUrl = globalServices.baseUrl + "admin/widget/list-text-widget";
return $http({method:"GET", url:getWidgetUrl})
.then(function(result){
return result.data;
});
};
return { getData: getData };
});
Calling section
var widget = getWidgets.getData()
.then(function (result) {
$scope.widgets = result;
$scope.$apply();
});
But it return an error getWidgets.getData is not a function.
What would be the root cause?
Change with this:
angular.module('dss')
.controller('widgetCtrl',
['$scope', '$compile', '$window', '$location', '$http', 'globalServices', 'getWidgets', 'Flash', '$timeout', '$sce', '$routeParams', widgetCtrl]);
function widgetCtrl($scope, $compile, $window, $location, $http, globalServices, getWidgets, Flash, $timeout, $sce, $routeParams) {
var widget = getWidgets.getData();
widget.then(
function (result) {
$scope.widgets = result; $scope.$apply();
});
}
EDIT: if you want an advice, use this syntax:
widgetCtrl.$inject = ['$scope', '$compile', '$window', '$location', '$http', 'globalServices', 'getWidgets', 'Flash', '$timeout', '$sce', '$routeParams'];
angular.module('dss').controller('widgetCtrl', widgetCtrl);
function widgetCtrl($scope, $compile, $window, $location, $http, globalServices, getWidgets, Flash, $timeout, $sce, $routeParams) {
var widget = getWidgets.getData();
widget.then(
function (result) {
$scope.widgets = result; $scope.$apply();
});
}
You are using a service and returning an object on its constructor.
Services get initialized as
new yourFunction and factories as yourFunction().
Switch it from service to factory and it will work.
EDIT: If you want to keep using a service, try this.
Note I changed the name of the service
function GetWidgetsService($http, globalServices){
this._$http = $http;
this._globalServices = globalServices;
}
GetWidgetsService.prototype.getData = function() {
var getWidgetUrl = this._globalServices.baseUrl + "admin/widget/list-text-widget";
// Angular $http() and then() both return promises themselves
return this._$http({method:"GET", url:getWidgetUrl}).then(function(result){
// What we return here is the data that will be accessible
// to us after the promise resolves
return result.data;
});
};
angular.module('yourModule').service('getWidgetsService', GetWidgetsService);
EDIT 2: For completeness, here is your fixed factory
angular.module('yourModule').factory('getWidgetsFactory', function ($http, globalServices) {
return {
getData: function () {
var getWidgetUrl = globalServices.baseUrl + 'admin/widget/list-text-widget';
// Angular $http() and then() both return promises themselves
return $http({method: 'GET', url: getWidgetUrl}).then(function (result) {
// What we return here is the data that will be accessible
// to us after the promise resolves
return result.data;
});
}
};
});
EDIT 3: HERE is a JSBin with your code working with my first solution.
Try this way
.service('getWidgets', function (globalServices, $http) {
return { getData: function() {
var getWidgetUrl = globalServices.baseUrl + "admin/widget/list-text-widget";
// Angular $http() and then() both return promises themselves
return $http({method:"GET", url:getWidgetUrl}).then(function(result){
// What we return here is the data that will be accessible
// to us after the promise resolves
return result.data;
});
};
};
});
So far this is the complete source
angular
.module('app')
.factory('Friends', ['$http',function($http){
return {
get: function(){
return $http.get('api/friends.json')
.then(function(response){
alert(JSON.stringify( response.data));
return response.data;
});
}
};
}])
Controller:
angular.module("app")
.controller('homeCtrl',['$scope','Friends',
function($scope, Friends){
$scope.title = "Welcome";
$scope.items=["2016","2015", "2014"];
$scope.friends = Friends.get();
$scope.save = function(){
$http.post('/api/friends', friends);
}
}])
$stateProvider
.state('home',{
url:'/',
templateUrl:'templates/home.html',
controller: 'homeCtrl',
resolve : {
friends:['Friends', function(Friends){
return Friends.get();
}]
}
})
The result when I try to alert it:
The UI Blank:
*and my nav bar ddl is not working how to do the trick?
Friends.get() return a promise. You must use the then method :
Friends.get().then(function(data) { $scope.friends = data; }); //instead of $scope.friends = Friends.get();
you should use $q for promises:
angular
.module('app')
.factory('Friends', ['$http', '$q' ,function($http, $q){
var self = {};
self.get = function() {
var deferred = $q.defer();
$http.get('api/friends.json')
.success(deferred.resolve)
.error(deferred.reject)
return deferred.promise;
}
return self
}])
Resolve:
resolve : {
friends:['Friends', function(Friends){
return Friends.get();
}]
}
I am not able to update my $scope.gs variable in the view using {{gs}} when I am doing http.get in the service. I tried reading some of the answers but they seem to suggest this method. Please help...
My service method is as below:
app.service('myService', function($http, $rootScope) {
this.getData = function(key){
return $http.get('/myapp/stocklist/AMZN').
then(function(data) {
return data;
});
}
//return this;
});
My controller is:
app.controller('graph', ['$scope', '$http', 'myService', function($scope,$http, myService){
myService.getData($scope.mySelected).then(function(codes){
$scope.gs= codes;
});
}]);
I am not sure if I should use factory instead of Service for this. Can you please advice?
possible to use $q
app.service('myService', function($http, $rootScope, $q) {
return {
getData: function (key) {
var deffered = $q.defer();
$http.get('/myapp/stocklist/AMZN')
.then(function (result) {
deffered.resolve(result.data);
}, function (error) {
deffered.reject(error);
});
return deferred.promise
}
}
});
or adjust your service to
app.service('myService', function($http, $rootScope, $q) {
return {
getData: function (key) {
$http.get('/myapp/stocklist/AMZN')
}
}
});
You use then twice. Try
Service
app.service('myService', function($http, $rootScope) {
this.getData = function(key){
return $http.get('/myapp/stocklist/AMZN');
});
});
Controller
app.controller('graph', ['$scope', '$http', 'myService', function($scope,$http, myService){
myService.getData($scope.mySelected).then(function(response){
$scope.gs= response.data;
});
}]);
I have a factory that request user data via an api call:
angular.module('MyApp')
.factory('UserApi', function($auth,Account){
return {
getProfile: function()
{
Account.getProfile()
.then(function(response){
return response.data; ----> returning json data ok!!
});
}
}
});
But when i call the function in controller, it return me undefined
myApp.controller('AppCtrl', function($rootScope,$state,$window,$document,$scope,$filter,$resource,cfpLoadingBar,$translate,UserApi){
$scope.user = function(){
UserApi.getProfile().then(function(data){
$scope.currentUser = data;
})
}
console.log($scope.user()); ----> undefined
});
account factory:
angular.module('MyApp')
.factory('Account', function($http){
return {
getProfile: function(){
return $http.get('/api/me');
}
}
});
The error that log in console is TypeError: Cannot read property 'then' of undefined
EDIT
The only available solution is to set the response.data to $rootScope.user in which the data will be available across the controllers.
angular.module('MyApp')
.factory('UserApi', function($auth,Account,$rootScope){
return {
getProfile: function()
{
Account.getProfile()
.then(function(response){
$rootScope.user = response.data; ----> returning json data ok!!
});
return $rootScope.user;
}
}
});
First of all getProfile method should return a promise (not undefined like it's doing in your code):
angular.module('MyApp')
.factory('UserApi', function($auth,Account){
return {
getProfile: function()
{
return Account.getProfile()
.then(function(response) {
return response.data;
});
}
}
});
then in controller you should use then callback:
myApp.controller('AppCtrl', function ($rootScope, $state, $window, $document, $scope, $filter, $resource, cfpLoadingBar, $translate, UserApi) {
$scope.user = function () {
UserApi.getProfile().then(function (data) {
$scope.currentUser = data;
console.log($scope.currentUser);
})
};
});
Also make sure you understand the difference between synchronous and asynchronous code, and why console.log($scope.user()) makes no sense in this case: response if not yet available when you try to log it. Instead you provide a callback to be called when data has come.
You are trying to return the data after the request is completed successfully. But, since this is an ajax call we don't know when it will be completed (Basically, runs on a different thread.). There are two ways you can resolve this.
1 - Just return the call like so.
angular.module('MyApp')
.factory('UserApi', function($auth,Account){
return {
getProfile: function(){
return Account.getProfile(); // return call and resolve in controller.
}
}
});
2 - You can use promise ($q)
angular.module('MyApp')
.factory('UserApi', function($auth,Account, $q){
return {
getProfile: function(){
var deferred = $q.defer();
Account.getProfile()
.success(function(data){
deferred.resolve(data);
});
return deferred.promise; // just return the promise
}
}
});
and in your controller just have the following.
myApp.controller('AppCtrl', function($rootScope,$state,$window,$document,$scope,$filter,$resource,cfpLoadingBar,$translate,UserApi){
$scope.user = function(){
UserApi.getProfile().then(function(data){
$scope.currentUser = data;
console.log($scope.currentUser);
});
}
});
EDITED:
You get undefined. Because:
there isn't return in $scope.user
your console.log($scope.user($scope.user()) works only initial time.
there is time delay for getting data from UserApi.getProfile()
Also, your codes have some mistakes:
I can suggest that:
Don't use your console.log($scope.user()) initial time.
Or, You should get all data initial time when factory created. Then, you use UserApi.data in your controller.(But, there is time delay. You may get success data, if request return response before from loading of your controller).
.
angular.module('MyApp')
.factory('UserApi', function ($auth, Account) {
var data;
Account.getProfile().then(function (response) {
data = response.data;
});
return {
data: data
}
});
myApp.controller('AppCtrl', function ($rootScope, $state, $window, $document, $scope, $filter, $resource, cfpLoadingBar, $translate, UserApi) {
console.log(UserApi.data);
});
I need to update view when new data created at server?
How to do this correct?
My controller
app.controller('MainController', ['$scope', 'games', function($scope, games) {
games.success(function(data) {
console.log(data[0]);
$scope.games = data[0];
});
}]);
My factory
app.factory('games', ['$http', function($http) {
return $http.get('./game')
.success(function(data) {
return data;
})
.error(function(data) {
return data;
});
}]);
Remember that services in Angular are objects. So create a simple method that returns a promise, to manage it in the controller.
Controller
app.controller('MainController', ['$scope', 'games', function($scope, games) {
games.get().then(function(data) {
console.log(data[0]);
$scope.games = data[0];
});
}]);
Service
app.service('games', ['$http', function($http) {
this.get = function() {
return $http.get('./game');
};
}]);
you can use $timeout if you do not wish to use websockets
$timeout(function(){
games.success(function(data) {
console.log(data[0]);
$scope.games = data[0];
});
},1000);
Update : sorry it should be $interval
$interval(function(){
games.success(function(data) {
console.log(data[0]);
$scope.games = data[0];
});
},1000);
Update : how to do this using factory
app.factory('games', ['$http', function($http) {
return {
getGame: function() {
return $http.get('./game');
}
}
}]);
Now in your controller
app.controller('MainController', ['$scope', 'games', function($scope, games) {
games.getGame().success(function(data) {
$scope.games = data[0];
});
}]);