How to change pyramid request to promises with $q - angularjs

I want to change this pyramid request to promises with $q.
app.controller('Ctrl', function ($scope, $http, $q) {
$http.post('http://localhost:1235',data_post1).success(function (data){
console.log("1");
$http.post('http://localhost:1236',data_post2).success(function (data){
console.log("2");
$http.post('http://localhost:1237',data_post3).success(function (data){
console.log("3");
$http.post('http://localhost:1238',data_post4).success(function (data){
console.log("4");
});
});
});
});
}
I'm never use $q before.

so best practice would be to pull the http requests out of the controller
so if you had a factory like
app.factory("fooSrvc", ["$q", "$http", function($q, $http){
return {
data1: function(postData){
var deferred = $q.defer();
$http.post("", postData).success(function(results){
deferred.resolve(results);
});
return deferred.promise;
},
data2: function(postData){
var deferred = $q.defer();
$http.post("", postData).success(function(results){
deferred.resolve(results);
});
return deferred.promise;
}
};
}]);
then your controller could look like
app.controller("Ctrl", ["$scope", "fooSrvc", function($scope, fooSrvc){
fooSrvc.data1(dataTopost).then(function(results){
// do something with it here possibly
fooSrvc.data2(moreDataToPost).then(function(moreResults){
// do something with it here possibly
});
});
}]);

Related

ui-router resolve use angular-loading-bar?

What I want to do is to use the ui-router resolution angular install-bar.
How can I run the codes given in Resolve?
resolve: {
return {
loadedData: function($rootScope, $q) {
var deferred = $q.defer();
$rootScope.$on('cfpLoadingBar:completed', function() {
console.log("complete");
deferred.resolve();
});
return deferred.promise;
}
};
}
In terms of being an example;
greeting: function($q, $timeout){
var deferred = $q.defer();
$timeout(function() {
deferred.resolve('Hello!');
}, 1000);
return deferred.promise;
}
Instead of
I want to run this code, it works every timeout.
Rootscope.on works only when the page is loaded.
greeting: function($q, $rootScope){
var deferred = $q.defer();
$rootScope.$on('cfpLoadingBar:completed', function(){
deferred.resolve('Hello!');
});
return deferred.promise;
}

every method of angular service have same line of code for promise ($deferred)

I am first time using angular JS so kindly bear my question. While creating service in angular JS I have to write var deferred = $q.defer(); and then return deferred.promise; in every method of service which use $http()
Is there any shorthand or alternative way to do so?
for eg:
(function() {
'use strict';
angular
.module('app')
.service('AuthService', function($q, $http, $interval, $timeout, BASE_URL) {
var service = {
login: function(formdata) {
var deferred = $q.defer();
$http.post(BASE_URL + '/api/getLogin', formdata).then(function(response) {
deferred.resolve(response);
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
},
signup: function(formdata) {
var deferred = $q.defer();
$http.post(BASE_URL + '/api/register', formdata).then(function(response) {
deferred.resolve(response);
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
},
forgot: function(formdata) {
var deferred = $q.defer();
$http.post(BASE_URL + '/api/forgot', formdata).then(function(response) {
deferred.resolve(response);
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
}
}
return service;
});
here you can see I have to rewrite the same line of code in every method of service
use $http methods without any other code:
return $http.post(BASE_URL + '/api/getLogin', formdata)
all $http methods return promise by default

Update data from a factory in another factory

I have two factories in my angular app.
app.factory('FavoritesArtists',['$http', '$q', 'UserService', function($http, $q, UserService){
var deferred = $q.defer();
var userId = UserService.getUser().userID;
$http.get('http://myurl.com/something/'+userId)
.success(function(data) {
deferred.resolve(data);
})
.error(function(err) {
deferred.reject(err);
});
return deferred.promise;
}]);
And I have a value I get from another factory :
var userId = UserService.getUser().userID;
But I doesn't update when the UserService.getUser() is changed, the view changes with $watch, but I don't know how it work inside a factory.
Any help is welcome, thanks guys !
Anyone ?
app.factory('FavoritesArtists',['$http', '$q', 'UserService', function($http, $q, UserService){
var deferred = $q.defer();
$http.get('https://homechefhome.fr/rise/favorites-artists.php?user_id='+userId)
.success(function(data) {
deferred.resolve(data);
})
.error(function(err) {
deferred.reject(err);
});
return deferred.promise;
}]);
I simply need to make userId variable dynamic..
A better design pattern will be this
app.factory('UserService',
['$http', function($http) {
var getUser = function() {
return http.get("url_to_get_user");
};
return {
getUser: getUser
};
}]);
app.factory('ArtistService',
['$http', '$q', 'UserService', function($http, $q, UserService) {
var getFavoriteArtists = function() {
UserService.getUser().then(function(response) {
var userId = response.data.userID;
return $http.get('http://myurl.com/something/' + userId);
}, function() {
//passing a promise for error too
return $q.reject("Error fetching user");
});
};
return {
getFavoriteArtists: getFavoriteArtists
};
}]);
Now call it in controller like,
ArtistService.getFavoriteArtists().then(function(response) {
//do something with response.data
}, function(response) {
//log error and alert the end user
});

angular JS $rootScope undefined inside $http.get

I want to retrieve data from an $http.get and put it in $rootScope :
.run
app.run(function ($rootScope, $q, $http, $timeout, stateRules) {
stateRules
.then(function (data) {
$rootScope.user = data;
console.log(data);
});
});
.service
app.service('stateRules', ['$http','$q', function($http, $q) {
var userUrl= 'api/user/';
var userService = {};
var deferred = $q.defer();
$http.get(userUrl+ "getUserName", { cache: true }).success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
});
.controller
app.controller('userCtrl', ['$scope', function ( $scope) {
console.log($scope.user);
}]);
but the value of the $scope.user in my controller is undefined. Any idea how to fix it ?
Thanks
$rootScope should be injected in a service. like this.
.service('ServiceGetSVC', ['$http','$rootScope','$q',function ($http,$rootScope,$q) {....}
Or if you try to use $rootScope.user after method get. It was undefined becouse method get asynchronous. Should use deferred.
in application
ServiceGetSVC.then(data){
$rootScope.user = data;
}
service
.service('stateRules', ['$http','$q' function($http, $q) {
var deferred = $q.defer();
$http.get(communUrl + "getUserName", { cache: true }).success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}])

AngularJS : returning data from service to controller

I am trying to create a service to get json and pass it to me homeCtrl I can get the data but when a pass it to my homeCtrl it always returns undefined. Im stuck.
My Service:
var myService = angular.module("xo").factory("myService", ['$http', function($http){
return{
getResponders: (function(response){
$http.get('myUrl').then(function(response){
console.log("coming from servicejs", response.data);
});
})()
};
return myService;
}
]);
My Home Controller:
var homeCtrl = angular.module("xo").controller("homeCtrl", ["$rootScope", "$scope", "$http", "myService",
function ($rootScope, $scope, $http, myService) {
$scope.goData = function(){
$scope.gotData = myService.getResponders;
};
console.log("my service is running", $scope.goData, myService);
}]);
You should return promise from getResponders function, & when it gets resolved it should return response.data from that function.
Factory
var myService = angular.module("xo").factory("myService", ['$http', function($http) {
return {
getResponders: function() {
return $http.get('myUrl')
.then(function(response) {
console.log("coming from servicejs", response.data);
//return data when promise resolved
//that would help you to continue promise chain.
return response.data;
});
}
};
}]);
Also inside your controller you should call the factory function and use .then function to get call it when the getResponders service function resolves the $http.get call and assign the data to $scope.gotData
Code
$scope.goData = function(){
myService.getResponders.then(function(data){
$scope.gotData = data;
});
};
This is an example how I did for my project, it work fine for me
var biblionum = angular.module('biblioApp', []);//your app
biblionum.service('CategorieService', function($http) {
this.getAll = function() {
return $http({
method: 'GET',
url: 'ouvrage?action=getcategorie',
// pass in data as strings
headers: {'Content-Type': 'application/x-www-form-urlencoded'} // set the headers so angular passing info as form data (not request payload)
})
.then(function(data) {
return data;
})
}
});
biblionum.controller('libraryController', function($scope,CategorieService) {
var cat = CategorieService.getAll();
cat.then(function(data) {
$scope.categories = data.data;//don't forget "this" in the service
})
});

Resources