Connecting a promise through two services - javascript

I'm a bit new to angular and am trying to understand how I can use a promise with two services.
In the code below in the App.js I call FirstService.get(), which should wait for the RestService to return the result. In the App.js I would like to use the .then() to wait for the result from FirstService.get().
My question how do I need to set up the promise in the First Service so that I can use the .then() in the App.js?
Thanks!
// App.js
FirstService.get().then(function(promise) {
// do something here with the result
}, function(response) {
console.log('error');
});
//First Service
oApp.service( 'FirstService', function( RestService, $localStorage, $q ) {
this.get = function( ) {
var url = o.buildServerUrl();
// Retrieve info
RestService.get(url, function(response) {
return response;
});
};
});
// Rest Service
oApp.service( 'RestService', function( $rootScope, $http ) {
this.get = function ( url, callback ) {
try {
$http.get(url).
success(function(data, status, headers, config) {
var response = o.processServerResponse(data, status);
callback(response);
}).
error(function(data, status, headers, config) {
var response = o.processServerResponse(data, status);
callback(response);
});
}
catch(err) {
var response = o.createExceptionResponse(err.message);
callback(response);
}
}
});

This should do it:
// App.js
FirstService.get().then(function(promise) {
// do something here with the result
}, function(response) {
console.log('error');
});
//First Service
oApp.service( 'FirstService', function( RestService, $localStorage, $q ) {
this.get = function( ) {
var deferred = $q.defer();
var url = o.buildServerUrl();
// Retrieve info
RestService.get(url, function(response) {
deferred.resolve(response);
});
return deferred.promise;
};
});
// Rest Service
oApp.service( 'RestService', function( $rootScope, $http ) {
this.get = function ( url, callback ) {
try {
$http.get(url).
success(function(data, status, headers, config) {
var response = o.processServerResponse(data, status);
callback(response);
}).
error(function(data, status, headers, config) {
var response = o.processServerResponse(data, status);
callback(response);
});
}
catch(err) {
var response = o.createExceptionResponse(err.message);
callback(response);
}
}
});

Related

Why are $scope and var variables undefined within my angular controller , as success seems to just hide values

I make a few different $http calls and I want to set either variable (var blah) or $scope to be set to an object value and persist at least down a few lines so that it can be sent to a 2nd $http request
I get undefined , why and how to fix / persist the variable or scope?
app.controller('detailController', function ($scope, $interval, $http, $routeParams, $window, sessionVariables, $httpParamSerializer) {
//$scope.xid = 1; // this seems to persist but NOT if i try update it in 1st $http.get
$http.get('/Umbraco/Api/ClientsApi/GetClient/' + clientId).
success(function (data, status, headers, config) {
console.log(data); // correctly shows me object of data
$scope.xid = data.Id; // DOES NOT WORK OUTSIDE OF this $http.get
console.log(data.Id); // yes shows data inside here
//console.log(data.IsSampleData); // contains data
$scope.client = data; // this is how is then use client object in view template
}).
error(function (data, status, headers, config) {
// log error
});
This is the problem, $scope.xid does is saying undefined
console.log('before');
console.log($scope.xid);
console.log('after');
Of which this 2nd $http.get call I want to append the xid onto the end of it
$http.get('/Umbraco/Api/ActivityApi/GetActivity').
success(function (data, status, headers, config) {
$scope.activity = data; // correctly gets data
}).
error(function (data, status, headers, config) {
// log error
});
Update : FULL CODE
app.controller('detailController', function ($scope, $interval, $http, $routeParams, $window, sessionVariables, $httpParamSerializer) {
var clientId = $routeParams.id;
//console.log(clientId);
//$scope.xid = 1;
$http.get('/Umbraco/Api/ClientsApi/GetClient/' + clientId).
success(function (data, status, headers, config) {
console.log(data);
//console.log(data.Id);
//console.log(data.IsSampleData);
$scope.client = data;
}).
error(function (data, status, headers, config) {
// log error
});
console.log('before');
console.log(client.Id);
console.log('after');
$http.get('/Umbraco/Api/ActivityApi/GetActivity').
success(function (data, status, headers, config) {
//console.log(data);
//console.log(data.IsSampleData);
$scope.activity = data;
}).
error(function (data, status, headers, config) {
// log error
});
});
Use Promises and chaining
var firstRequest = $http.get(url).then(function (result) {
/* optional - do something with result, pass through to next .then() */
return result;
});
var secondRequest = firstRequest.then(function (result) {
return $http.get(otherUrl);
});
var thirdREquest = secondRequest.then(function () {
/* and so on */
});
You are setting $scope.xid once the promise returnet by $http.get() is resolved.
Actually the console.log($scope.xid) executes before than the assignment!
If you want to use the result of a first promise, you can chain promises like this:
$http.get('/Umbraco/Api/ClientsApi/GetClient/' + clientId)
.then(function(response) {
return $http.get('/Umbraco/Api/ActivityApi/GetActivity' + response.Id)
)
.then(function(response2) {
// Proccess response2
});
try this:
app.controller('detailController', function ($scope, $interval, $http, $routeParams, $window, sessionVariables, $httpParamSerializer) {
var clientId = $routeParams.id;
//console.log(clientId);
//$scope.xid = 1;
$http.get('/Umbraco/Api/ClientsApi/GetClient/' + clientId).then(function (response) {
console.log(response.data);
//console.log(response.data.Id);
//console.log(response.data.IsSampleData);
$scope.client = response.data;
// second HTTP call with chained client ID received from the first call
$http.get('/Umbraco/Api/ActivityApi/GetActivity/' + response.data.Id).then(function (response2) {
//console.log(response2.data);
//console.log(response2.data.IsSampleData);
$scope.activity = response2.data;
}).catch(function (error) {
// log error
});
}).catch(function (error) {
// log error
});
// this code is outside of $http promise as it is executed before promise resolve
// so, at this point $scope.client.Id is undefined
//console.log('before');
//console.log($scope.client.Id);
//console.log('after');
});
This code does seem to "work" Any reason why I should NOT do this?
$http.get('/Umbraco/Api/ClientsApi/GetClient/' + clientId).
success(function (data, status, headers, config) {
$scope.client = data;
$scope.getActivity(data); // CALL HERE
}).
error(function (data, status, headers, config) {
// log error
});
$scope.getActivity = function(data) {
$http.get('/Umbraco/Api/ActivityApi/GetActivity').
success(function(data, status, headers, config) {
$scope.activity = data;
}).
error(function(data, status, headers, config) {
// log error
});
};
use then() for $http according to official documentation
$http.get('/Umbraco/Api/ActivityApi/GetActivity').then(
function success(response) {
console.log(response.data);
console.log(response.data.Id);
$scope.client = response.data;
},
function error(response) {
console.log(response);
}
);
EDIT !
Http is asynchronous, it take some time to do it.
It mean that $http is called, and the answer IS NOT WAITED. the code after it is runned immediatly !
console.log("before $http");
$http.get('/Umbraco/Api/ActivityApi/GetActivity').then(
function success(response) {
console.log("http success");
$scope.client = response.data;
},
function error(response) {
console.log("http error");
console.log(response);
}
);
// this will be logged before the success/error of http
console.log("after $http");
If you want to do something when success is done, create a function for it and call it from success/error

Angular Js Factory doen't return values to controller

My factory returns undefined when I invoke the method getPopularMovies in factory using controller, Am not sure what mistake I have done here, Please let me know
my factory
angular.module('ngMovies').factory('moviesFactory', function ($http) {
var movies = [];
function getPopularMovies() {
var popularmoviesurl = "https://api.themoviedb.org/3/movie/popular?api_key=adf3d78d5c0f38313a68de730f02063a";
return $http({method: 'GET', url: popularmoviesurl}).success(function (data, status, headers, config) {
if (status == 200) {
movies = data.results;
} else {
console.error('Error happened while getting the movie list.')
}
}).error(function (data, status, headers, config) {
console.error('Error happened while getting the movie list.')
});
return movies;
}
return {
getPopularMovies: getPopularMovies
}
});
controller
angular.module('ngMovies').controller('popularmoviesController', ['moviesFactory', '$scope', function (moviesFactory, $scope) {
$scope.popularmovies = moviesFactory.getPopularMovies();
}]);
I suggest to use promises for asynchronous processes.
function getPopularMovies()
{
var deferred = $q.defer();
var popularmoviesurl = "https://api.themoviedb.org/3/movie/popular?api_key=adf3d78d5c0f38313a68de730f02063a";
$http({method:'GET',url:popularmoviesurl}).
success(function (data, status, headers, config) {
if (status == 200) {
deferred.resolve(data.results);
} else {
console.error('Error happened while getting the movie list.')
deferred.reject();
}
}).error(function (data, status, headers, config) {
deferred.reject();
console.error('Error happened while getting the movie list.')
});
return deferred.promise;
}
and then inside your controller just use
moviesFactory.getPopularMovies().then(function(data){
$scope.popularmovies = data;
},function(){
// your error handling
})
service:
angular
.module('ngMovies')
.factory('moviesFactory', function($http) {
function getPopularMovies(callback) {
var popularmoviesurl = "https://api.themoviedb.org/3/movie/popular?api_key=adf3d78d5c0f38313a68de730f02063a";
return $http({
method: 'GET',
url: popularmoviesurl
}).
success(function(data, status, headers, config) {
if (status == 200) {
callback(data.results);
} else {
console.error('Error happened while getting the movie list.')
}
}).
}
return {
getPopularMovies: getPopularMovies
}
});
controller:
angular
.module('ngMovies')
.controller('popularmoviesController', ['moviesFactory', '$scope', function(moviesFactory, $scope) {
moviesFactory.getPopularMovies(function(movies){
$scope.popularmovies = movies;
});
}]);
Change your controller code like this:
angular.module('ngMovies').controller('popularmoviesController', ['moviesFactory', '$scope', function (moviesFactory, $scope) {
moviesFactory.getPopularMovies().then(function(data) {
$scope.popularmovies = data.results;
});
}]);
And in the getPopularMovies method return movies; statement is not required since you have already returned above in the same method.

How to returning data from a resource using angular

I'm creating service layers to interact with Rest server, but I've got some problems with ngResource promises.
var grupogestion= angular.module('app.grupogestion.services', ['ngResource']);
grupogestion.factory('Grupogestion', ['$resource', function ($resource){
return $resource('api/grupogestiones/:action/:id.:format',
{
action: '#action', id:'#id', format:'json'
},
{
'get': {method:'GET'},
'post': {method:'POST',headers : {'Content-Type': 'application/x-www-form-urlencoded'}},
'save': {method: 'POST',headers : {'Content-Type': 'application/x-www-form-urlencoded'}}
}
);
}]);
grupogestion.service('GrupogestionService',['Grupogestion', function (Grupogestion){
this.findAll = function (){
Grupogestion.get({action: 'index'},function (data, status, headers, config){
return data;
});
}
this.save = function (grupogestion){
Grupogestion.save({'action':'add'},$.param(grupogestion)).$promise.then(
function(data){
alert('k');
return data;
},
function(error){
alert('j');
return error;
}
);
}
}]);
When I call var response = GrupogestionService.save(data) from angular controller, I don't get the data at the same time I call the function, so the question is: How can I modify GrupogestionService for returning data to the controller?
I've tried to return the promise but I couldn't do it. Thanks for helping.
// service code
grupogestion.service('GrupogestionService', ['Grupogestion', function (Grupogestion) {
this.findAll = function () {
Grupogestion.get({action: 'index'}, function (data, status, headers, config) {
return data;
});
};
this.save = function (grupogestion) {
return Grupogestion.save({'action': 'add'}, $.param(grupogestion));
}
}]);
//run in your controller
var response = GrupogestionService.save(data).$promise.then(
function (data) {
alert('k');
return data;
},
function (error) {
alert('j');
return error;
}
);

AngularJS : Service not Returning Variables to Controllers

My app has a service that is supposed to return an array of objects (tweets from the twitter api) that looks like:
.service('twitterService', function($http) {
this.getTweets = function(){
$http.get('http://example.com/?json=get_twitter_sidebar').success(
function(data, status, headers, config) {
if (data.status == 'ok') {
return data.feed;
} else {
return 'Error Retrieving Feed'
}
});
}
})
This service seems to work; it calls the api and returns the desired object array (I used console.log to verify). However, I can't seem to pass the returned array to my controller:
var TopPageCtrl = function($scope, $window, $http, twitterService) {
$scope.feed = twitterService.getTweets();
};
When I use console.log($scope.feed), it returns undefined. I've tried a million approaches but nothing seems to work. What am I doing wrong?
return the promise
.service('twitterService', function($http) {
this.getTweets = function(){
var p = $http.get('http://example.com/?json=get_twitter_sidebar').success(
function(data, status, headers, config) {
if (data.status == 'ok') {
return data.feed;
} else {
return 'Error Retrieving Feed';
}
});
return p;
}});
var TopPageCtrl = function($scope, $window, $http, twitterService) {
twitterService.getTweets().then(function (response) {
$scope.feed = response;
};};
Maybe it's returning a promise that needs to be resolved? Try something like...
var getFeed = twitterService.getTweets();
getFeed.then(function (feed) {
$scope.feed = feed;
});
$scope.feed = twitterService.getTweets();
this.getTweets = function(){
$http.get('http://example.com/?json=get_twitter_sidebar').success(
function(data, status, headers, config) {
if (data.status == 'ok') {
return data.feed;
} else {
return 'Error Retrieving Feed'
}
});
}
Your function isn´t returning anything, that´s why you are getting "undefined"..
Try this:
this.getTweets = function(){
return $http.get('http://example.com/?json=get_twitter_sidebar').success(
function(data, status, headers, config) {
if (data.status == 'ok') {
return data.feed;
} else {
return 'Error Retrieving Feed'
}
});
}
twitterService.getTweets().then(function (response){...});

Pass data from service to controller in angularjs

Following is my Service code -
myApp.service('loginServiceChk', function(){
this.getInfo = {};
this.chkLogin = function($http,$location,$window){
$http.get('/users/chklogin')
.success(function (data, status, headers, config) {
if (data.code!="200"){
this.getInfo = {};
$window.location.href='/#/users/login';
}else{
this.getInfo = data.usersession;
}
});
};
});
My controller code -
myApp.controller('userDash',function($scope,$http,$location,loginServiceChk,$window){
loginServiceChk.chkLogin($http,$location,$window);
console.log(loginService.getInfo);
$scope.userLogout = function() {
$http.get('/users/logout').success(function (data, status, headers, config) {
if (data.logout=="200"){
merInfo = {} ;
$window.location.href='/#/userss/login';
}
})
};
});
However I am always getting an empty object in the console ( console.log(loginService.getInfo); ) . Let me know what I am doing wrong here.
I am expecting session data in the this.getInfo.
EDIT
If I am using .then then it is going in the if ie if (data.code!="200"){ here.
You have to wait for the promise.
Use this in your controller:
loginServiceChk.chkLogin($http,$location,$window).then(function() {
console.log(loginService.getInfo);
});
And add return to your service:
this.chkLogin = function($http,$location,$window){
return $http.get('/users/chklogin')
.then(function (data, status, headers, config) {
if (data.code!="200"){
this.getInfo = {};
$window.location.href='/#/users/login';
}else{
this.getInfo = data.usersession;
}
});
};

Categories

Resources