Passing variable from success call in service through controller to view - angularjs

In my ui-bootstrap modal I have 3 modal-body div's.
<div class="modal-body" ng-show="$ctrl.selected.item == 'registration'">...</div>
<div class="modal-body" ng-show="$ctrl.selected.item == 'thanks'">...</div>
<div class="modal-body" ng-show="$ctrl.selected.item == 'error'">...</div>
By changing $ctrl.selected.item I change HTML inside my modal window. Now I need to change this variable(property of object indeed) inside a registerService which is injected do registerwindow' controller.
app.service('registerService', ['$http', 'localStorageService', function ($http, localStorageService) {
this.registerUser = function (registerInfo) {
$http({
url: 'http://localhost:3000/v1/sign_up',
headers: {
'Content-Type' : 'application/json'
},
method: 'POST',
data: {
email: registerInfo.email,
nick: registerInfo.nick,
password: registerInfo.password,
password_confirmation: registerInfo.password_confirmation
}
})
.then(function successCall(response) {
console.log('user added'); // delete it
$ctrl.selected.item = $ctrl.items[1];
}, function errorCall(respone) {
console.log('error callback register ');
console.log(respone.data);
$ctrl.selected.item = $ctrl.items[2];
})
};
}]);
This approach with $ctrl.selected.item = $ctrl.items[1]; doesn't work obviously.. How can I do this? I have no clue I need to do this asynchronously.

You could probably use Angular's $q service to handle this. The service's method would look like this:
this.registerUser = function (registerInfo) {
var deferred = $q.defer();
$http({
url: 'http://localhost:3000/v1/sign_up',
headers: {
'Content-Type' : 'application/json'
},
method: 'POST',
data: {
email: registerInfo.email,
nick: registerInfo.nick,
password: registerInfo.password,
password_confirmation: registerInfo.password_confirmation
}
})
.then(function successCall(response) {
console.log('user added'); // delete it
//$ctrl.selected.item = $ctrl.items[1];
deferred.resolve(); //Resolve the promise - success
}, function errorCall(respone) {
console.log('error callback register ');
console.log(respone.data);
//$ctrl.selected.item = $ctrl.items[2];
deferred.reject(); //Reject the promise - failure
});
return deferred.promise;
};
Remember to inject $q into your service!
Within your controller, you'd call your service method like so, then adjust the scope variable within the .then and .catch:
registerService.registerUser(registerInfo)
.then(function() {
$scope.selected.item = $scope.items[1];
//Not sure what your controller looks like, you may be using controllerAs, so this will be a bit different
})
.catch(function() {
$scope.selected.item = $scope.items[2];
});

Related

return a value from $get factory method when calling service from controller in AngularJs

Im trying to call service from controller which gives me below error..
Provider 'loginService' must return a value from $get factory method.
Below is my code.What is that im doing wrong.
CONTROLLLER CODE
app.controller('loginController', ['$scope', '$http', 'loginService', function ($scope, $http, loginService) {
$scope.checkdata = function () {
var userName = $scope.username;
var password = $scope.password;
//Call the login service
loginService.validateUser(userName, password);
alert(response.data);
}
}])
Service code
app.factory('loginService', function ($http) {
this.validateUser = function (userName, password) {
var userData = new Object();
userData.userName = userName;//Data.username;
userData.password = password;//Data.password;
return $http({
url: "http://localhost:53181/api/User",
dataType: 'json',
method: 'POST',
data: userData,
headers: {
"Content-Type": "application/json"
}
}).then(function (response) {
alert(response);
if (response.data && response.data.data && response.data.data.length == 1)
return response.data.data[0];
});
}
});
Create service funtcion like this:
yourAPICallingFuntion: function() {
var url = "your url";
var deferred = $q.defer();
$http.get(url, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).then(function(data) {
deferred.resolve(data.data);
}, function(error) {
deferred.reject(error);
});
return deferred.promise;
}
In Controller Call like this:
loginService.yourAPICallingFuntion().then(function(data){
//Now this will give you response in form of data
//you can this data according to your requirement
});
factory service is expected to return a value from factory function. It doesn't have this context (it's either window or undefined).
If you want to use this like this.validateUser = ..., use service service instead.

Angular 1.5 - passing http post response to controller

I am trying to pass an http response from my controller to a service, it works well except for getting the response to go into the controller here is my code below:
For my service
app.factory('ApiService',function($http,Config,$q){
return {
login: function(payload,callBack){
var deferred = $q.defer();
$http({
method:'POST',
url:Config.baseUrl + '/api/login',
data:payload,
headers: {'Content-Type': 'application/json'},
}).then(function successCallback(callBack){
console.log(callBack);
return deferred.resolve(callBack);
}, function errorCallback(callBack){
//deferred.reject(error);
console.log(callBack);
return deferred.reject(callBack);
});
return deferred.promise;
}
}
});
and for the Controller
app.controller('LoginCtrl', function($scope,$position,$rootScope,$state,ApiService) {
$scope.forms = {
'loginForm':''
}
var payload ={
'username':'',
'password':''
}
$scope.userLogin = function(form){
$scope.username = form.username.$modelValue;
$scope.password = form.password.$modelValue;
payload ={
"username":$scope.username,
"password":$scope.password
}
ApiService.login(payload, function(result){
console.log(result);
}
});
Now I don't understand because when I console.log() the response I'm able to see it in the service but doing the same on the controller I'm getting nothing.
No need to make it complex. Simply return promise from factory and use it in controller.
factory:
app.factory('ApiService',function($http,Config,$q) {
return {
login: function(payload) {
return $http({
method:'POST',
url:Config.baseUrl + '/api/login',
data:payload,
headers: {'Content-Type': 'application/json'},
});
}
}
});
in controller :
ApiService.login(payload).then(function(data){
// use response data
}, function(error) {
// handle error
});
You should use it like this:
ApiService.login(payload).then(function(result){
console.log(result);
});
Because you are returning a promise in your service.
Also you don't need that callback parameter, because the then method on the promise is your callback when it finishes and you can access the data your resolve it with.
app.factory('ApiService',function($http,Config,$q){
return {
login: function(payload){
var deferred = $q.defer();
$http({
method:'POST',
url:Config.baseUrl + '/api/login',
data:payload,
headers: {'Content-Type': 'application/json'},
}).then(function (result){
return deferred.resolve(result);
}, function (result){
return deferred.reject(result);
});
return deferred.promise;
}
}
});

update $scope info from another controller

How can i make the testservice factory return the result from the post request?, or make the app, factory update some $scope details thats within the overallcontroller ?
how can i update information within the overallcontroller from another controller?
app.factory('testservice', ['$http', 'auth', function($http, auth) {
var o = {
posts : []
};
o.test = function() {
return $http.post('/poster', null, {
headers: {Authorization: 'Bearer '+auth.getToken()}
}).success(function(data){
console.log(Data);
});
};
return o;
}]);
app.controller('overallController', ['$scope', 'posts', 'testservice', 'auth','$interval',
function($scope, posts, testservice, auth, $interval) {
$scope.data = {cash:"12879999",location:"test2",gang:"None","username":"test",
xp: 1290,
health: 100,
wanted: 30,
energy: 90};
var databackground = function() {
console.log("logging...");
var t = testservice.test;
console.log(t);
}
databackground();
$interval(databackground, 30000);
}]);
example html
<div class="main" ng-controller="overallController">
<section class="sides left" style="background:blue; height:100px;">
<ul>
<li ng-hide="isLoggedIn()">Logg inn</li>
</ul>
</section>
<div ng-controller"othercontroller">
// call made from some code here
</div>
</div>
Change your service to
o.test = function() {
return $http.post('/poster', null, {
headers: {Authorization: 'Bearer '+auth.getToken()}
}).then(function(response){
return response.data;
});
};
And in your controller, do call the service, and get the results back in the promise:
testservice.test().then(function(data) {
$scope.data = data;
});
Read more about how to use promises here
You return the promise from your service, you would listen for that to resovle and get hold of your data.
Using $rootScope is heavy handed approach and should be used as a last resort. Services and event are preferable.
var databackground = function() {
console.log("logging...");
testservice.test()
.then(function (res) {
console.log(res.data); //Here is your data
});
}
EDIT: Your service should change slightly also. Firstly .success and .error are deprecated. Use .then and .catch instead.
If you wish to just return data out of your service just do:
o.test = function() {
return $http.post('/poster', null, {
headers: {
Authorization: 'Bearer ' + auth.getToken()
}
});
};
However if you want to transform the data in your service you can but ensure your return it or your controller wont get anything:
o.test = function() {
return $http.post('/poster', null, {
headers: {
Authorization: 'Bearer ' + auth.getToken()
}
})
.then(function (res) {
res.data.test = 'lol';
return res;
})
};
Try referencing $rootScope instead of $scope.
This will allow controllers and factories to interact with each other.

Ajax in AngularJS Service

Created an Angular Service:
calculator_app.service('FillOpportunity', function () {
this.fill_opportunity = function (path,scope) {
$.ajax({
url: 'opportunitycalculator/calculator/GetProducts?idstring=' + path,
type: "GET",
cache: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data)
{
scope.opportunity_data = data;
scope.$apply();
},
error: function () {
}
});
};
});
Called the service on ng-change of a dropdown:
FillOpportunity.fill_opportunity($scope.result_path,$scope);
The scope.opportunity_data is binded to the select in UI:
<select id="seloppurtunityproducts" name="selproducttype" multiple="" style="height:300px" ng-model="opportunity_products" ng-options="a for a in opportunity_data"></select>
On ng-Change, Ajax is called when I check in Network of Chrome, but the value is not updated in the select box.
Any inputs?
Don't use jQuery's ajax. Use the built in $http. Using $http automatically begins the digest cycle of angular's builtin compiler. If you must use jquery... then you'd have to call $scope.$apply(); every time there is a data change.
Service:
calculator_app.factory("calcService", ["$http", function($http) {
return {
getItem: function(url, items) {
return $http.get(url,
// query string like { userId: user.id } -> ?userId=value
{ params: items });
}
}
}]);
Inject the service into your controller and use:
calculator_app.controller("MainCtrl", ["calcService", "$scope", function(calcService, $scope) {
$scope.opportunity_data = [];
var payload = {
idstring: path
};
//call the service
calcService.getItem('path/to/calc/api', payload).then(function(response) {
$scope.opportunity_data = response.data;
}).catch(function(response) {
alert('error' + response.data);
});
}]);

$http POST & $http GET in 1 service

I want create 1 service where i can POST the data and on success i can again GET the data and update the $scope.variable??
How to do that?
I've tried this way:
angular.module('mvc')
.factory('ajaxService', function($http) {
return {
getAjaxData: function(response) {
$http.get(url).success(response);
return response;
},
postAjaxdata: function(postData){
$http({
method: "post",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
url: url,
data: data
})
.success(function(response){
ajaxService.getAjaxData(function(response) {
$scope.foo = response;
});
});
}
}
});
Capture this in postAjaxdata() to be used in the success callback to call getAjaxData().
You don't have access to the scope inside of the service (nor do you want to access it from a service). The Angular convention is to return a promise to the controller so that it can apply the response value to the scope when the promise is resolved. You can also do this using callbacks (to be consistent with the code that was posted). Here, I've added a callback to postAjaxdata()...
angular.module('mvc')
.factory('ajaxService', function($http) {
return {
getAjaxData: function(successCallback) {
$http.get(url).success(successCallback);
return successCallback;
},
postAjaxdata: function(postData, successCallback){
var that = this;
$http({
method: "post",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
url: url,
data: data
})
.success(function(){
that.getAjaxData(successCallback);
});
}
}
});
The controller should look something like this...
function controller ($scope, ajaxService) {
// ...
ajaxService.postAjaxdata(postData, function (response) {
$scope.foo = response;
});
}
The main issue is that you can't set scope variables in the way you attempted to from the service.
You could instead use the $q service to return a promise which, when resolved, is set to your $scope.foo variable:
.factory('ajaxService', function($http, $q) {
var ajaxService = {
getAjaxData: function() {
return $http.get(url);
},
postAjaxdata: function(postData){
var deferred = $q.defer();
$http({
method: "post",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
url: url,
data: postData
})
.success(function(){
deferred.resolve(ajaxService.getAjaxData());
});
return deferred.promise;
}
};
return ajaxService;
});
You'll also notice that I set the body of your factory to a named variable, which you can then use to call functions internally (as you did with ajaxService.getAjaxData()) before returning.
Then, in your controller, you could set your scope variable like this:
.controller('MyController', function($scope, ajaxService){
ajaxService.postAjaxdata().then(function(results){
$scope.foo = results.data;
})
})
Working Plunker
Note: my answer is not entirely dissimilar to Anthony Chu's. I noticed that he posted his just before mine, but I went ahead anyway since mine takes a slightly different approach, utilizing promises instead of callbacks.

Resources